Skip to content

Commit

Permalink
Merge pull request #192 from wonsik3686/React-정원식-Sprint6
Browse files Browse the repository at this point in the history
[정원식] Sprint6
  • Loading branch information
wlgns2223 authored Jun 30, 2024
2 parents 9461c5d + 966e847 commit 417f694
Show file tree
Hide file tree
Showing 22 changed files with 757 additions and 52 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

#file
visualwind.wrapper.tsx

# dependencies
/node_modules
/.pnp
Expand Down
5 changes: 4 additions & 1 deletion src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ function App() {
<Route path="/signup" element={<Signup />} /> */}
<Route path="faq" element={<Faq />} />
<Route path="privacy" element={<Privacy />} />
<Route path="items" element={<Items />} />
<Route path="items">
<Route index element={<Items />} />
<Route path="additems" element={<AddItems />} />
</Route>
<Route path="additems" element={<AddItems />} />
</Routes>
</BrowserRouter>
Expand Down
5 changes: 5 additions & 0 deletions src/assets/images/icons/ic_X.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/images/icons/ic_union.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 14 additions & 6 deletions src/components/items/BestItems/BestItems.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,24 @@ function BestItems() {
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(4);
const [keyword, setKeyword] = useState('');
// 에러
const [fetchingError, setfetchingError] = useState(null);

const fetchItemList = async ({ order, page, pageSize, keyword }) => {
let products = await getProducts({ order, page, pageSize, keyword });
setItemList(products.list);
try {
setfetchingError(null);
const products = await getProducts({ order, page, pageSize, keyword });
setItemList(products.list);
} catch (err) {
setItemList([]);
setfetchingError(err);
}
};
const handleResize = () => {
setPageSize(getPageSize());
};

useEffect(() => {
const handleResize = () => {
setPageSize(getPageSize());
};

window.addEventListener('resize', handleResize);
fetchItemList({ order, page, pageSize, keyword });

Expand All @@ -47,6 +54,7 @@ function BestItems() {
<div className="title-best-items">베스트 상품</div>

<div className="list-best-items">
{fetchingError && fetchingError.message}
{itemList?.map((item) => (
<Item item={item} key={`best-item-${item.id}`} />
))}
Expand Down
33 changes: 33 additions & 0 deletions src/components/items/PaginationBar/PaginatinoBar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.pagination-bar {
display: flex;
align-items: center;
justify-content: center;
}

.btn-pagination {
border: 1px solid #e5e7eb;
border-radius: 50%;
width: 40px;
height: 40px;
color: #6b7280;
font-weight: 600;
font-size: 16px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20px;
}

.btn-pagination:last-child {
margin-right: 0;
}

.btn-pagination:disabled {
cursor: default;
opacity: 0.5;
}

.btn-pagination.active {
background-color: var(--blue);
color: #fff;
}
55 changes: 55 additions & 0 deletions src/components/items/PaginationBar/PaginationBar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from 'react';
import './PaginatinoBar.css';
import { ReactComponent as IconArrowLeft } from '../../../assets/images/icons/arrow_left.svg';
import { ReactComponent as IconArrowRight } from '../../../assets/images/icons/arrow_right.svg';

function PaginationBar({ totalPageNum, activePageNum, onPageChange }) {
const maxVisiblePages = 5;
let startPage;

if (totalPageNum <= maxVisiblePages) {
startPage = 1;
} else {
startPage = Math.max(activePageNum - Math.floor(maxVisiblePages / 2), 1);
startPage = Math.min(startPage, totalPageNum - maxVisiblePages + 1);
}

const pages = Array.from(
{ length: Math.min(maxVisiblePages, totalPageNum - startPage + 1) },
(_, i) => startPage + i
);
return (
<>
<div className="pagination-bar">
<button
className="btn-pagination"
disabled={activePageNum === 1}
onClick={() => onPageChange(activePageNum - 1)}
>
<IconArrowLeft />
</button>
{/* 반복 */}
{pages.map((page) => (
<button
key={page}
className={`btn-pagination ${
activePageNum === page ? 'active' : ''
}`}
onClick={() => onPageChange(page)}
>
{page}
</button>
))}
<button
className="btn-pagination"
disabled={activePageNum === totalPageNum}
onClick={() => onPageChange(activePageNum + 1)}
>
<IconArrowRight />
</button>
</div>
</>
);
}

export default PaginationBar;
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import './SailItems.css';
import { ReactComponent as IconSearch } from '../../../assets/images/icons/ic_search.svg';
import { ReactComponent as IconSort } from '../../../assets/images/icons/ic_sort.svg';
import { useEffect, useState } from 'react';
import { getProducts } from '../../../pages/api/Items';
import Item from '../Item/Item';
import PaginationBar from '../PaginationBar/PaginationBar';
import './SellingItems.css';

const getPageSize = () => {
const width = window.innerWidth;
Expand All @@ -16,7 +17,7 @@ const getPageSize = () => {
}
};

function SailItems() {
function SellingItems() {
// 상품
const [itemList, setItemList] = useState([]);
// 쿼리
Expand All @@ -26,7 +27,14 @@ function SailItems() {
const [keyword, setKeyword] = useState('');
// 검색
const [isDropdownVisible, setIsDropdownVisible] = useState(false);
// 페이지네이션
const [totalPageNum, setTotalPageNum] = useState();
// 에러
const [fetchingError, setfetchingError] = useState(null);

const handlePageChange = (pageNumber) => {
setPage(pageNumber);
};
const handleClickDropdown = () => {
setIsDropdownVisible(!isDropdownVisible);
};
Expand All @@ -42,8 +50,16 @@ function SailItems() {
};

const fetchItemList = async ({ order, page, pageSize, keyword }) => {
let products = await getProducts({ order, page, pageSize, keyword });
setItemList(products.list);
try {
setfetchingError(null);
const products = await getProducts({ order, page, pageSize, keyword });
setItemList(products.list);
setTotalPageNum(Math.ceil(products.totalCount / pageSize));
} catch (err) {
setItemList([]);
setTotalPageNum(0);
setfetchingError(err);
}
};

useEffect(() => {
Expand All @@ -60,15 +76,15 @@ function SailItems() {

return (
<>
<div className="container-sail-items">
<div className="container-selling-items">
{/* 판매 중인 상품 헤더 */}
<div className="header-sail-items">
<div className="header-sail-items-left">
<div className="title-sail-items">판매 중인 상품</div>
<div className="header-selling-items">
<div className="header-selling-items-left">
<div className="title-selling-items">판매 중인 상품</div>
</div>
<div className="header-sail-items-right">
<div className="header-selling-items-right">
<a
href="/additems"
href="/items/additems"
id="btn-add-item"
className="button btn-add-item"
>
Expand Down Expand Up @@ -107,14 +123,26 @@ function SailItems() {
</div>
</div>
{/* 판매 중인 상품 목록 */}
<div className="list-sail-items">
{fetchingError && (
<div className="list-selling-items-error">
{fetchingError.message}
</div>
)}
<div className="list-selling-items">
{itemList?.map((item) => (
<Item item={item} key={`sail-item-${item.id}`} />
<Item item={item} key={`selling-item-${item.id}`} />
))}
</div>
<div className="wrapper-pagination-bar">
<PaginationBar
totalPageNum={totalPageNum}
activePageNum={page}
onPageChange={handlePageChange}
/>
</div>
</div>
</>
);
}

export default SailItems;
export default SellingItems;
16 changes: 10 additions & 6 deletions src/components/navigationBar/NavigationBar.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,37 @@
border-bottom: 1px solid #dfdfdf;
}

.navbarLeft {
.navbar-left {
display: flex;
align-items: center;
}

.navbarHomeLogo {
.navbar-home-logo {
width: 153px;
}

.navbarMenu {
.navbar-menu {
margin: 0 15px;
text-decoration: none;
}

.navbarMenu ol {
.navbar-menu ol {
list-style-type: none;
padding-left: 0;
}

.navbarMenuItem {
.navbar-menu-item {
display: inline-block;
margin: 10px;
font-size: 18px;
font-weight: bold;
}

.navbarMenuItem.active {
.navbar-menu-item.active {
color: var(--blue);
}

.nav-bar-menu-link.active {
color: var(--blue);
}

Expand Down
37 changes: 27 additions & 10 deletions src/components/navigationBar/NavigationBar.jsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,46 @@
import { useEffect, useState } from 'react';
import { NavLink } from 'react-router-dom';
import imgPandaMarketLogo from '../../assets/images/logo/panda-market-logo.png';
import './NavigationBar.css';

function NavigationBar() {
return (
<header className="navbar">
<div className="navbarLeft">
<div className="navbar-left">
<a href="/">
<img
className="navbarHomeLogo"
className="navbar-home-logo"
src={imgPandaMarketLogo}
alt="판다마켓 홈"
/>
</a>
<nav className="navbarMenu">
<nav className="navbar-menu">
<ol>
<li className="navbarMenuItem navbar-menu-board">
<a href="/board" value="board">
<li className="navbar-menu-item navbar-menu-board">
{/* <a href="/board" value="board">
자유게시판
</a>
</a> */}
<NavLink
to={'/community'}
className={({ isActive }) =>
`nav-bar-menu-link ${isActive ? 'active' : ''}`
}
>
자유게시판
</NavLink>
</li>
<li className="navbarMenuItem navbar-menu-items">
<a href="/items" value="items">
<li className="navbar-menu-item navbar-menu-items">
{/* <a href="/items" value="items">
중고마켓
</a> */}
<NavLink
to={'/items'}

className={({ isActive }) =>
`nav-bar-menu-link ${isActive ? 'active' : ''}`
}
>
중고마켓
</a>
</NavLink>
</li>
</ol>
</nav>
Expand Down
Loading

0 comments on commit 417f694

Please sign in to comment.