Skip to content

Commit

Permalink
Merge pull request #115 from nori-dongsan/viewProduct/#112
Browse files Browse the repository at this point in the history
[ View Product ] 페이지네이션 및 가격 정렬 구현
  • Loading branch information
Happhee authored Jul 20, 2022
2 parents 7031def + cb91b5a commit 9c766a4
Show file tree
Hide file tree
Showing 58 changed files with 17,524 additions and 3,637 deletions.
10 changes: 5 additions & 5 deletions components/collectionProduct/CollectionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ export default function CollectionList(props: CollectionListProps) {
const { toyList } = props;
return (
<StToyListWrapper>
{toyList.map((toy, idx) => (
{toyList.map(({ image, title, price, month, siteUrl }, idx) => (
<ToyPreview
key={idx}
src={toy.image}
src={image}
store="그린키드그린키드그린키드그린키드그린키드그린키드그린키드그린키드그린키드그린키드그린키드"
title={toy.title}
price={toy.price}
title={title}
price={price}
age="36개월이상"
siteUrl={toy.siteUrl}
siteUrl={siteUrl}
/>
))}
</StToyListWrapper>
Expand Down
5 changes: 3 additions & 2 deletions components/collectionProduct/ToyPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ export default function ToyPreview(props: ToyPreviewProps) {
const { src, store, title, price, age, siteUrl } = props;
const [isMark, setIsMark] = useState(false);

const handleToySite = () => {
window.open(siteUrl);
const handleToySite = (e: React.MouseEvent<HTMLElement>) => {
if (!(e.target instanceof SVGElement)) window.open(siteUrl);
};

const handleToyMark = () => {
setIsMark((prev) => !prev);
};
Expand Down
33 changes: 29 additions & 4 deletions components/common/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,50 @@
import styled from '@emotion/styled';
import Link from 'next/link';
import { IcNoriHeaderLogo, IcSearchIcon } from '../../public/assets/icons';
import React, { useState } from 'react';
import Router from 'next/router';

export default function Header() {
const [inputValue, setInputValue] = useState<string>('');

const handleInputValue = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);
};

const handleClick = () => {
Router.push({
pathname: '/viewProduct',
query: { search: inputValue },
});
};

return (
<StHeaderWrapper className="mainHeader">
<StTopLink>
<p>
<a>고객센터</a> | <a>마이페이지</a> | <a href="/login">로그인</a>
<a>고객센터</a> | <a>마이페이지</a> |
<Link href="/login">
<a>로그인</a>
</Link>
</p>
</StTopLink>
<StHeaderContents>
<Link href="/main">
<Link href="/">
<a>
<IcNoriHeaderLogo />
</a>
</Link>
<StSearchWrapper>
<StSearchBar>
<input type="text" placeholder="상품명, 스토어명을 검색해보세요!" />
<IcSearchIcon />
<input
type="text"
maxLength={60}
placeholder="상품명, 스토어명을 검색해보세요!"
onChange={handleInputValue}
/>
<Link href="/viewProduct">
<IcSearchIcon onClick={handleClick} />
</Link>
</StSearchBar>
<StMenu>
<Link href="/viewProduct">
Expand Down
88 changes: 88 additions & 0 deletions components/common/PageNavigation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import styled from '@emotion/styled';
import { css } from '@emotion/react';
import {
IcLeftArrow,
IcLeftArrowFill,
IcRightArrow,
IcRightArrowFill,
} from '../../public/assets/icons';

interface PageNavigationProps {
currentPage: number;
lastPage: number;
handleCurrentPage: (nextPage: number) => void;
}

export default function PageNavigation(props: PageNavigationProps) {
const { currentPage, lastPage, handleCurrentPage } = props;

const pageArray =
currentPage % 5 === 0
? new Array(5)
.fill(0)
.map((_, idx) => (Math.floor(currentPage / 5) - 1) * 5 + idx + 1)
: lastPage > Math.ceil(currentPage / 5) * 5
? new Array(5)
.fill(0)
.map((_, idx) => Math.floor(currentPage / 5) * 5 + idx + 1)
: new Array(lastPage - Math.floor(currentPage / 5) * 5)
.fill(0)
.map((_, idx) => Math.floor(currentPage / 5) * 5 + idx + 1);

const handlePreviousGroupPage = () => {
handleCurrentPage(pageArray[0] - 1);
};
const handleNextGroupPage = () => {
handleCurrentPage(pageArray[pageArray.length - 1] + 1);
};

const handlePageNumber = (e: React.MouseEvent<HTMLAnchorElement>) => {
const target = e.target as HTMLAnchorElement;
handleCurrentPage(Number(target.innerHTML));
};
return (
<StNavigationWrapper>
{Math.floor(currentPage / 5) >= 1 && currentPage !== 5 ? (
<IcLeftArrowFill onClick={handlePreviousGroupPage} />
) : (
<IcLeftArrow />
)}
{pageArray.map((page) => (
<StPageNumberA
key={page}
isCurrent={page === currentPage}
onClick={() => handleCurrentPage(page)}
>
{page}
</StPageNumberA>
))}
{lastPage > Math.ceil(currentPage / 5) * 5 ? (
<IcRightArrowFill onClick={handleNextGroupPage} />
) : (
<IcRightArrow />
)}
</StNavigationWrapper>
);
}

const StNavigationWrapper = styled.nav`
display: flex;
justify-content: space-around;
align-items: center;
width: 22.2rem;
margin-bottom: 12rem;
cursor: pointer;
`;
const StPageNumberA = styled.a<{ isCurrent: boolean }>`
${({ isCurrent }) =>
isCurrent
? css`
color: #1db981;
`
: css`
color: #787878;
`};
${({ theme }) => theme.fonts.b3_16_medium_140}
`;
45 changes: 45 additions & 0 deletions components/common/PriceFilter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import styled from '@emotion/styled';

export interface PriceFilterProps {
priceDesc: boolean;
handleClickPrice: (clickPrice: string) => void;
}

export default function PriceFilter(props: PriceFilterProps) {
const { priceDesc, handleClickPrice } = props;

return (
<StPriceSection>
<StPriceTitle
onClick={() => handleClickPrice('price-desc')}
priceDesc={priceDesc}
>
낮은 가격순
</StPriceTitle>
<span>|</span>
<StPriceTitle
onClick={() => handleClickPrice('price-asc')}
priceDesc={!priceDesc}
>
높은 가격순
</StPriceTitle>
</StPriceSection>
);
}

const StPriceSection = styled.section`
display: flex;
align-items: center;
column-gap: 1.4rem;
height: 2rem;
margin-top: 2rem;
color: ${({ theme }) => theme.colors.gray005};
${({ theme }) => theme.fonts.b5_14_medium_140};
`;
const StPriceTitle = styled.span<{ priceDesc: boolean }>`
color: ${({ priceDesc, theme: { colors } }) =>
priceDesc ? colors.black : colors.gray005};
cursor: pointer;
`;
51 changes: 48 additions & 3 deletions components/common/WriteHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,47 @@
import styled from '@emotion/styled';
import { IcWriteHeaderLogo } from '../../public/assets/icons';
import Link from 'next/link';
import { useRecoilState } from 'recoil';
import { newPostInfoState } from '../../core/atom';
import { postCommunity } from '../../core/api/community';
import { useRouter } from 'next/router';

export default function WriteHeader() {
const [newPostInfo, setNewPostInfo] = useRecoilState(newPostInfoState);
const router = useRouter();
const { pathname } = useRouter();

const handleRegister = async () => {
const { title, content } = newPostInfo;
if (title === '' || content === '') {
alert('내용을 입력해주세요.');
return;
}

const data = await postCommunity(newPostInfo);
setNewPostInfo({
category: '후기',
title: '',
content: '',
});
router.push(`/community/${data.id}`);
};

return (
<StWriteHeaderWrapper>
<Link href="/main">
<Link href="/community">
<a>
<IcWriteHeaderLogo />
</a>
</Link>
<StWriteBtn>등록하기</StWriteBtn>
{pathname === '/community' ? (
<StModifyBlock>
<StCancleBtn>취소</StCancleBtn>
<StWriteBtn>수정완료</StWriteBtn>
</StModifyBlock>
) : (
<StWriteBtn>등록하기</StWriteBtn>
)}
</StWriteHeaderWrapper>
);
}
Expand All @@ -22,7 +53,7 @@ const StWriteHeaderWrapper = styled.section`
position: sticky;
top: -3.2em;
width: 100%;
width: 192rem;
height: 11.4rem;
padding-top: 4.2rem;
Expand All @@ -37,6 +68,8 @@ const StWriteBtn = styled.a`
justify-content: center;
align-items: center;
margin-left: 11.4rem;
width: 10rem;
height: 4.2rem;
Expand All @@ -47,3 +80,15 @@ const StWriteBtn = styled.a`
cursor: pointer;
`;
const StCancleBtn = styled(StWriteBtn)`
margin-left: 0rem;
background-color: ${({ theme }) => theme.colors.white};
color: ${({ theme }) => theme.colors.mainDarkgreen};
border: 0.1rem solid ${({ theme }) => theme.colors.mainDarkgreen};
`;
const StModifyBlock = styled.div`
display: flex;
gap: 1.4rem;
`;
2 changes: 2 additions & 0 deletions components/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ export { default as Error404 } from './Error404';
export { default as Header } from './Header';
export { default as Footer } from './Footer';
export { default as WriteHeader } from './WriteHeader';
export { default as PriceFilter } from './PriceFilter';
export { default as PageNavigation } from './PageNavigation';
45 changes: 45 additions & 0 deletions components/community/CommunityCategory.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import styled from '@emotion/styled';

interface CommunityCategoryProps {
category: string;
}

export default function CommunityCategory(props: CommunityCategoryProps) {
const { category } = props;

return (
<>
{category === '후기' ? (
<StCategoryReview>{category}</StCategoryReview>
) : category === '질문' ? (
<StCategoryQuestion>{category}</StCategoryQuestion>
) : (
<StCategoryInfo>{category}</StCategoryInfo>
)}
</>
);
}

const StCategory = styled.div`
display: flex;
justify-content: center;
align-items: center;
width: 7.6rem;
height: 2.6rem;
border-radius: 1.9rem;
color: ${({ theme }) => theme.colors.white};
${({ theme }) => theme.fonts.b5_14_medium_140}
`;
const StCategoryReview = styled(StCategory)`
background-color: ${({ theme }) => theme.colors.mainDarkgreen};
`;
const StCategoryQuestion = styled(StCategory)`
color: ${({ theme }) => theme.colors.gray009};
background-color: ${({ theme }) => theme.colors.subYellow};
`;
const StCategoryInfo = styled(StCategory)`
background-color: ${({ theme }) => theme.colors.mainGreen};
`;
8 changes: 5 additions & 3 deletions components/community/CommunityFloatingBtn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ const StCommunityFloatingBtnWrapper = styled.section`
display: flex;
flex-direction: column;
row-gap: 2.4rem;
align-items: cetner;
position: sticky;
top: 43rem;
align-items: center;
position: fixed;
bottom: 3rem;
right: 22.5%;
left: 77.5%;
height: 30rem;
margin-top: 8.8rem;
Expand Down
Loading

0 comments on commit 9c766a4

Please sign in to comment.