Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,080 changes: 1,996 additions & 84 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
<<<<<<< HEAD
<<<<<<< HEAD
=======
"react-paginate": "^8.2.0",
>>>>>>> React-정혜연-sprint6
=======
>>>>>>> c20238f3d1067618eaf8bd5e79e46823cdf525cb
"react-router-dom": "^6.22.3",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
Expand Down Expand Up @@ -35,5 +42,14 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@eslint/js": "^9.16.0",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-react": "^7.37.2",
"globals": "^15.13.0",
"prettier": "^3.4.2",
"typescript-eslint": "^8.17.0"
}
}
9 changes: 4 additions & 5 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { BrowserRouter, Route, Routes } from "react-router-dom";
import HomePage from "./pages/HomePage/HomePage";
import LoginPage from "./pages/LoginPage/LoginPage";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Header from "./components/Layout/Header";
import Hompage from "./pages/HomePage/HomePage";
import MarketPage from "./pages/MarketPage/MarketPage";
import LoginPage from "./pages/LoginPage/LoginPage";
import AddItemPage from "./pages/AddItemPage/AddItemPage";
import CommunityFeedPage from "./pages/CommunityFeedPage/CommunityFeedPage";
import Header from "./components/Layout/Header";

function App() {
return (
<BrowserRouter>
{/* Global Navigation Bar */}
<Header />

<div className="withHeader">
Expand Down
26 changes: 4 additions & 22 deletions src/api/itemApi.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,12 @@
const BASE_URL = "https://panda-market-api.vercel.app";

export async function getProducts(params = {}) {
// URLSearchParams을 이용하면 파라미터 값을 자동으로 쉽게 인코딩할 수 있어요.
const query = new URLSearchParams(params).toString();

try {
const response = await fetch(`${BASE_URL}/products?${query}`);
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
const body = await response.json();
return body;
} catch (error) {
console.error("Failed to fetch products:", error);
throw error;
}
}

export async function createProduct(formData) {
try {
const response = await fetch(`${BASE_URL}/products`, {
method: "POST",
body: formData,
});
const response = await fetch(
`https://panda-market-api.vercel.app/products?${query}`
);
if (!response.ok) {
throw new Error("상품 게시를 실패했습니다.");
throw new Error(`HTTP ERROR : ${response.status}`);
}
const body = await response.json();
return body;
Expand Down
13 changes: 6 additions & 7 deletions src/components/Layout/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import React from "react";
import Logo from "../../assets/images/logo/logo.svg";
import { Link, NavLink } from "react-router-dom";
import Logo from "../../assets/images/logo/logo.svg";
import "./Header.css";

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

function Header() {
return (
<header className="globalHeader">
<div className="headerLeft">
<Link to="/" className="headerLogo" aria-label="홈으로 이동">
<img src={Logo} alt="판다마켓 로고" width="153" />
<Link to="/" className="headerLogo">
<img src={Logo} alt="판다마켓 로고" />
</Link>

<nav>
<ul>
<li>
Expand All @@ -31,7 +31,6 @@ function Header() {
</ul>
</nav>
</div>

<Link to="/login" className="loginLink button">
로그인
</Link>
Expand Down
7 changes: 7 additions & 0 deletions src/components/UI/DropdownList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,11 @@ function DropdownList({ onSortSelection }) {
</div>
);
}
<<<<<<< HEAD
<<<<<<< HEAD
=======

>>>>>>> React-정혜연-sprint6
=======
>>>>>>> c20238f3d1067618eaf8bd5e79e46823cdf525cb
export default DropdownList;
8 changes: 8 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
<<<<<<< HEAD
<<<<<<< HEAD
import "./styles/global.css"; // index.js에서 global stylesheet을 import하면 전역적으로 스타일이 적용돼요
=======
import "./styles/global.css";
>>>>>>> React-정혜연-sprint6
=======
import "./styles/global.css"; // index.js에서 global stylesheet을 import하면 전역적으로 스타일이 적용돼요
>>>>>>> c20238f3d1067618eaf8bd5e79e46823cdf525cb

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
Expand Down
6 changes: 6 additions & 0 deletions src/pages/AddItemPage/AddItemPage.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import React from "react";
<<<<<<< HEAD

function AddItemPage() {
return <div>AddItemPage</div>;
=======
import { useState } from "react";
import { createProduct } from "../../api/itemApi";
import FileInput from "./FileInput.jsx";
Expand Down Expand Up @@ -105,6 +110,7 @@ function AddItemPage({ onSubmitSuccess }) {
{submittingError && <div>{submittingError.message}</div>}
</form>
);
>>>>>>> c20238f3d1067618eaf8bd5e79e46823cdf525cb
}

export default AddItemPage;
18 changes: 9 additions & 9 deletions src/pages/MarketPage/components/AllItemsSection.jsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { getProducts } from "../../../api/itemApi";
import ItemCard from "./ItemCard";
import PagenationBar from "../../../components/UI/PaginationBar";
import { ReactComponent as SortIcon } from "../../../assets/images/icons/ic_sort.svg";
import { ReactComponent as SearchIcon } from "../../../assets/images/icons/ic_search.svg";
import { Link } from "react-router-dom";
import DropdownList from "../../../components/UI/DropdownList";
import PaginationBar from "../../../components/UI/PaginationBar";

const getPageSize = () => {
const width = window.innerWidth;

if (width < 768) {
// Mobile viewport
return 4;
} else if (width < 1280) {
// Tablet viewport
return 6;
} else {
// Desktop viewport
return 10;
}
};
Expand Down Expand Up @@ -45,28 +43,30 @@ function AllItemsSection() {
setPageSize(getPageSize());
};

// 화면 크기 변경할 때마다 pageSize를 다시 계산해 넣음
//화면크기 변경시 페이지사이즈 다시 계산
window.addEventListener("resize", handleResize);
fetchSortedData({ orderBy, page, pageSize });

// Cleanup function
return () => {
window.removeEventListener("resize", handleResize);
};
}, [orderBy, page, pageSize]);

//토글 드롭다운 기본값
const toggleDropdown = () => {
setIsDropdownVisible(!isDropdownVisible);
};

//전달받은 pageNumbber로 페이지 적용(setPage)
const onPageChange = (pageNumber) => {
setPage(pageNumber);
};

return (
<div>
<div className="allItemsSectionHeader">
<h1 className="sectionTitle">판매 중인 상품</h1>
<h1 className="sectionTitle">전체 상품</h1>

<Link to="/additem" className="loginLink button">
상품 등록하기
</Link>
Expand All @@ -77,7 +77,7 @@ function AllItemsSection() {
<SearchIcon />
<input
className="searchBarInput"
placeholder="검색할 상품을 입력해 주세요"
placeholder="검색할 상품을 입력해주세요"
/>
</div>
<div className="sortButtonWrapper">
Expand Down
11 changes: 6 additions & 5 deletions src/pages/MarketPage/components/BestItemsSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@ import { getProducts } from "../../../api/itemApi";
const getPageSize = () => {
const width = window.innerWidth;
if (width < 768) {
// Mobile viewport
return 1;
} else if (width < 1280) {
// Tablet viewport
return 2;
} else {
// Desktop viewport
return 4;
}
};
Expand All @@ -30,11 +27,15 @@ function BestItemsSection() {
setPageSize(getPageSize());
};

// 화면 크기 변경할 때마다 pageSize를 다시 계산해 넣음
// 이벤트 리스너 추가
window.addEventListener("resize", handleResize);

// 디팬던시 배열이 변경되면 하위 코드 실행

// 가져온 데이터 나타내기
fetchSortedData({ orderBy: "favorite", pageSize });

// Cleanup function
// 이벤트 리스너 제거 (*이벤트 중첩 방지)
return () => {
window.removeEventListener("resize", handleResize);
};
Expand Down
9 changes: 7 additions & 2 deletions src/pages/MarketPage/components/ItemCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ import { ReactComponent as HeartIcon } from "../../../assets/images/icons/ic_hea

function ItemCard({ item }) {
return (
<div className="itemCard">
<div className="itemcard">
<img src={item.images[0]} alt={item.name} className="itemCardThumbnail" />
<div className="itemSummary">
<h2 className="itemName">{item.name}</h2>
<p className="itemPrice">{item.price.toLocaleString()}원</p>
<p className="itemPrice">
{item.price.toLocaleString(
("ko-KR", { style: "currency", currency: "KRW" })
)}
</p>
<div className="favoriteCount">
<HeartIcon />
{item.favoriteCount}
Expand Down
Binary file added 중고마켓.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading