Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JR-714] 검색 페이지 구현 #139

Merged
merged 36 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
27ecb0e
feat: react query key 추가
Leejha Sep 9, 2023
21ff15c
feat: axios interceptors에 토큰 만료시 로그아웃 기능 추가
Leejha Sep 13, 2023
a94890f
feat: 토큰이 필요없을 때 사용할 axios instance 추가
Leejha Sep 13, 2023
b0bdc47
chore: http 폴더 추가
Leejha Sep 13, 2023
3148c91
refactor: post뿐만 아니라 get의 역할도 하고 있으므로 네이밍 수정
Leejha Sep 13, 2023
cde66b3
feat: 외부 이미지를 허용하는 설정 추가
Leejha Sep 14, 2023
c49465a
chore: hooks 패키지에 peerDependency 추가
Leejha Sep 14, 2023
17c3288
feat: hooks 패키지에 intersection observer 훅 추가
Leejha Sep 14, 2023
8223ac4
feat: hook 패키지에 infinite scroll 훅 추가
Leejha Sep 14, 2023
72bf71c
feat: 공통 타입 추가
Leejha Sep 14, 2023
2c4ad0b
refactor: post뿐만 아니라 get의 역할도 하고 있으므로 네이밍 수정
Leejha Sep 14, 2023
bd58da3
feat: 전통주 리스트를 가져오는 api 추가
Leejha Sep 14, 2023
3d81866
refactor: 타입의 응집도를 높이기 위해 공통 타입 사용
Leejha Sep 14, 2023
8668a1e
feat: 전통주 인포 페이지 url 추가
Leejha Sep 14, 2023
14fc158
feat: 정렬 옵션 상수화
Leejha Sep 14, 2023
ff9c8b2
feat: 지역명과 몇명이 즐겼는지를 보여주는 컴포넌트 추가
Leejha Sep 14, 2023
a2a9e67
feat: 주루마블의 디자인에 맞게 select 컴포넌트 수정
Leejha Sep 14, 2023
8b68fc5
feat: search input에 상태 관리를 위한 코드 추가
Leejha Sep 14, 2023
6596296
feat: 전통주 정보 컴포넌트 검색 페이지에서도 사용할 수 있도록 구현
Leejha Sep 14, 2023
6f8ab61
feat: 검색 페이지에서 사용하는 전통주 투표 컴포넌트 구현
Leejha Sep 14, 2023
dece2a5
feat: 전통주 리스트를 무한 스크롤로 가져오는 서비스 구현
Leejha Sep 14, 2023
17e4296
feat: 전통주 투표를 무한 스크롤로 가져오는 서비스 구현
Leejha Sep 14, 2023
6c8ee93
refactor: Chip 컴포넌트를 사용하도록 수정
Leejha Sep 14, 2023
4c18a9d
refactor: sort type에 공통 타입 적용
Leejha Sep 14, 2023
d079e1a
feat: 정렬 옵션 select box 구현
Leejha Sep 14, 2023
2769a94
feat: 지역 필터 select box 구현
Leejha Sep 14, 2023
b1fb8f5
fix: 오타 수정
Leejha Sep 14, 2023
f631c93
feat: expand more 아이콘 추가
Leejha Sep 14, 2023
d3de353
feat: 쿼리키 추가
Leejha Sep 14, 2023
df6c448
feat: 전통주 리스트 구현
Leejha Sep 14, 2023
326f060
feat: 전퉁주 투표 리스트 구현
Leejha Sep 14, 2023
bb4ac5a
feat: 전통주 투표에서 칩을 보여주는 컴포넌트 구현
Leejha Sep 14, 2023
d1664a0
feat: 전통주 투표에서 투표 정보를 보여주는 컴포넌트 구현
Leejha Sep 14, 2023
f54f265
feat: 검색 페이지 구현
Leejha Sep 14, 2023
fba54f6
fix: 새로운 의존성 반영
Leejha Sep 14, 2023
627c1b3
fix: 음식점 추가 모달 임시 주석 처리
Leejha Sep 14, 2023
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
24 changes: 19 additions & 5 deletions .pnp.cjs

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

3 changes: 3 additions & 0 deletions apps/jurumarble/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ const nextConfig = {
styledComponents: true,
},
transpilePackages: ["@monorepo/ui, @monorepo/hooks"],
images: {
domains: ["shopping-phinf.pstatic.net"],
},
};

module.exports = nextConfig;
66 changes: 66 additions & 0 deletions apps/jurumarble/src/app/search/components/ChipContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { UseMutateFunction } from "@tanstack/react-query";
import Chip from "components/Chip";
import React from "react";
import SvgIcBookmarkActive from "src/assets/icons/components/IcBookmarkActive";
import SvgIcBookmark from "src/assets/icons/components/IcBookmark";
import styled from "styled-components";

interface Props {
title: string;
date: string;
region: string;
mutateBookMark: UseMutateFunction;
isBookmark: boolean;
}

const ChipContainer = ({ date, title, region, mutateBookMark, isBookmark }: Props) => {
return (
<>
<TagRow>
<FlexRow>
{region && <Chip variant="region">{region}</Chip>}
<Chip variant="numberOfParticipants">122명이 즐겼어요</Chip>
</FlexRow>
<FlexRow>
{isBookmark ? (
<SvgIcBookmarkActive width={20} height={20} onClick={() => mutateBookMark()} />
) : (
<SvgIcBookmark width={20} height={20} onClick={() => mutateBookMark()} />
)}
</FlexRow>
</TagRow>
<TitleRow>
{title}
{/* <DateText>{date.slice(0, 10)}</DateText> */}
</TitleRow>
<DateText>{date}</DateText>
</>
);
};

const TagRow = styled.div`
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
`;

const TitleRow = styled.div`
display: flex;
margin-top: 20px;
${({ theme }) => theme.typography.body01};
`;

const DateText = styled.div`
color: ${({ theme }) => theme.colors.black_04};
${({ theme }) => theme.typography.body_long03}
text-align: right;
margin: 8px 0 20px;
`;

const FlexRow = styled.div`
display: flex;
gap: 4px;
`;

export default ChipContainer;
58 changes: 58 additions & 0 deletions apps/jurumarble/src/app/search/components/DrinkList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Button } from "components/button";
import DrinkItem from "components/DrinkItem";
import { SortType } from "src/types/common";
import styled, { css } from "styled-components";
import useSearchDrinkService from "../services/useDrinkService";

interface Props {
searchText: string;
sortOption: string;
regionOption: string;
isSelectedTab: boolean;
}

function DrinkList({ searchText, sortOption, regionOption, isSelectedTab }: Props) {
const { drinkList, fetchNextPage, hasNextPage } = useSearchDrinkService({
page: 0,
size: 3,
keyword: searchText,
region: regionOption,
sortBy: sortOption as SortType,
});

if (!drinkList) {
return <></>;
}

const onClickFetchNextPage = () => {
hasNextPage && fetchNextPage();
};

return (
<Container>
{drinkList.map((drinkInfo) => (
<DrinkItem key={drinkInfo.id} drinkInfo={drinkInfo} />
))}
{!isSelectedTab && (
<MoreButton variant="outline" width="100%" height="48px" onClick={onClickFetchNextPage}>
우리술 정보 더보기
</MoreButton>
)}
</Container>
);
}

const Container = styled.div`
display: flex;
flex-direction: column;
gap: 8px;
margin-top: 24px;
`;

const MoreButton = styled(Button)`
${({ theme }) => css`
${theme.typography.body01}
margin: 24px 0 40px 0;
`};
`;
export default DrinkList;
51 changes: 51 additions & 0 deletions apps/jurumarble/src/app/search/components/DrinkVoteItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Vote } from "lib/apis/vote";
import Path from "lib/Path";
import { useRouter } from "next/navigation";
import useBookmarkService from "services/useBookmarkService";
import styled from "styled-components";
import ChipContainer from "./ChipContainer";
import VoteDescription from "./VoteDescription";

interface Props {
voteDrink: Vote;
}
/**
*
* @Todo 타입 더 깔끔하게 정의 필요
*/
function DrinkVoteItem({ voteDrink }: Props) {
const { voteId, region, title, imageA, imageB } = voteDrink;

const { mutateBookMark, bookMarkCheckQuery } = useBookmarkService(voteId);

const { data: bookmarkCheck } = bookMarkCheckQuery;

const isBookmark = bookmarkCheck?.bookmarked || false;

const router = useRouter();
const onClickDrinkVoteItem = () => {
router.push(`${Path.VOTE_DETAIL_PAGE}/${voteId}`);
};

return (
<Container onClick={onClickDrinkVoteItem}>
<ChipContainer
title={title}
date="20.08.22"
region={region}
mutateBookMark={mutateBookMark}
isBookmark={isBookmark}
/>
<VoteDescription imageA={imageA} imageB={imageB} />
</Container>
);
}

const Container = styled.button`
border-radius: 10px;
border: 1px solid ${({ theme }) => theme.colors.line_02};
box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.08), 0px 10px 25px 0px rgba(0, 0, 0, 0.06);
padding: 20px;
`;

export default DrinkVoteItem;
58 changes: 58 additions & 0 deletions apps/jurumarble/src/app/search/components/DrinkVoteList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Button } from "components/button";
import styled, { css } from "styled-components";
import useVoteDrinkService from "../services/useVoteDrinkService";
import DrinkVoteItem from "./DrinkVoteItem";

interface Props {
searchText: string;
sortOption: string;
regionOption: string;
isSelectedTab: boolean;
}

function DrinkVoteList({ searchText, sortOption, regionOption, isSelectedTab }: Props) {
const { voteDrinkList, fetchNextPage, hasNextPage } = useVoteDrinkService({
page: 0,
size: 3,
keyword: searchText,
region: regionOption,
sortBy: sortOption,
});

if (!voteDrinkList) {
return <></>;
}

const onClickFetchNextPage = () => {
hasNextPage && fetchNextPage();
};

return (
<Container>
{voteDrinkList.map((voteDrink, index) => (
<DrinkVoteItem key={`drinkVoteItem_${index}`} voteDrink={voteDrink} />
))}
{!isSelectedTab && (
<MoreButton variant="outline" width="100%" height="48px" onClick={onClickFetchNextPage}>
우리술 투표 더보기
</MoreButton>
)}
</Container>
);
}

const Container = styled.div`
display: flex;
flex-direction: column;
margin-top: 24px;
gap: 8px;
`;

const MoreButton = styled(Button)`
${({ theme }) => css`
${theme.typography.body01}
margin: 24px 0 40px 0;
`};
`;

export default DrinkVoteList;
62 changes: 62 additions & 0 deletions apps/jurumarble/src/app/search/components/RegionSmallSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { REGION_LIST, SORT_LIST } from "lib/constants";
import styled, { css } from "styled-components";
import { useToggle } from "@monorepo/hooks";
import SvgIcExpandMore from "src/assets/icons/components/IcExpandMore";
import { Select } from "components/selectBox";

interface Props {
defaultOption: string;
onChangeSortOption: (id: string) => void;
}

REGION_LIST.unshift({ value: "", label: "지역" });

function RegionSmallSelect({ defaultOption, onChangeSortOption }: Props) {
const [isOpen, onToggleOpen] = useToggle();

return (
<SelectStyled isOpen={isOpen}>
<Select
defaultValue={defaultOption}
onChangeSelectedOption={onChangeSortOption}
options={REGION_LIST}
isOpen={isOpen}
onToggleOpen={onToggleOpen}
>
<SvgIcExpandMore width={20} height={20} />
</Select>
</SelectStyled>
);
}

const SelectStyled = styled.span<{ isOpen: boolean }>`
${({ theme, isOpen }) => css`
${theme.typography.button01};
color: ${theme.colors.black_03};
width: 80px;
height: 40px;
.selected-label {
border: 1px solid ${theme.colors.line_01};
border-radius: 8px;
padding: 10px 12px;
width: 96px;
}
svg {
${isOpen && "transform: rotateX( 180deg )"}
}
`}
#select-list {
width: 100px;
height: 200px;
overflow: auto;
display: flex;
flex-direction: column;
gap: 16px;
padding: 8px 0;
}
#indicator {
display: flex;
}
`;

export default RegionSmallSelect;
Loading