From 27ecb0ebd5e67ce1af495fb5c6f75b97597d559d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Sat, 9 Sep 2023 23:03:37 +0900 Subject: [PATCH 01/36] =?UTF-8?q?feat:=20react=20query=20key=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jurumarble/src/lib/queryKeys.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/jurumarble/src/lib/queryKeys.ts b/apps/jurumarble/src/lib/queryKeys.ts index d49ea6cd..c58217f1 100644 --- a/apps/jurumarble/src/lib/queryKeys.ts +++ b/apps/jurumarble/src/lib/queryKeys.ts @@ -1,10 +1,18 @@ export const queryKeys = { MAIN_VOTE_LIST: "mainVoteList" as const, BOOKMARK_CHECK: "bookmarkCheck" as const, + USER_INFO: "userInfo" as const, + VOTE_LIST: "voteList" as const, + RESTAURANT_LIST: "restaurantList" as const, + DRINK_LIST: "drinkList" as const, }; export const reactQueryKeys = { // @note any 처리 mainVoteList: () => [queryKeys.MAIN_VOTE_LIST] as const, bookmarkCheck: () => [queryKeys.BOOKMARK_CHECK] as const, + userInfo: () => [queryKeys.USER_INFO], + voteList: (params: any) => [queryKeys.VOTE_LIST, ...params], + restaurantList: (params: any) => [queryKeys.RESTAURANT_LIST, ...params], + drinkList: (params: any) => [queryKeys.DRINK_LIST, ...params], }; From 21ff15cd368a82e724100739447b66afbcc2ac75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Thu, 14 Sep 2023 01:09:25 +0900 Subject: [PATCH 02/36] =?UTF-8?q?feat:=20axios=20interceptors=EC=97=90=20?= =?UTF-8?q?=ED=86=A0=ED=81=B0=20=EB=A7=8C=EB=A3=8C=EC=8B=9C=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=95=84=EC=9B=83=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/lib/apis/{ => http}/http.ts | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) rename apps/jurumarble/src/lib/apis/{ => http}/http.ts (69%) diff --git a/apps/jurumarble/src/lib/apis/http.ts b/apps/jurumarble/src/lib/apis/http/http.ts similarity index 69% rename from apps/jurumarble/src/lib/apis/http.ts rename to apps/jurumarble/src/lib/apis/http/http.ts index 967ddf4f..37b17a35 100644 --- a/apps/jurumarble/src/lib/apis/http.ts +++ b/apps/jurumarble/src/lib/apis/http/http.ts @@ -2,6 +2,7 @@ import axios from "axios"; import type { AxiosInstance, AxiosRequestConfig } from "axios"; import { SERVER_URL } from "lib/constants"; import userStorage from "lib/utils/userStorage"; +import { logout } from "lib/utils/auth"; const axiosInstance = axios.create({ baseURL: SERVER_URL, @@ -22,7 +23,33 @@ export const http = axiosInstance; axiosInstance.interceptors.response.use( (response) => response, - (originalError) => Promise.reject(originalError), + + async (error) => { + const { + response: { status }, + } = error; + + switch (status) { + case 401: + const tokens = userStorage.get(); + if (!tokens) throw new Error("No tokens found"); + + alert("로그인이 만료되었습니다. 다시 로그인해주세요."); + + logout(); + + break; + + case 409: + throw new Error(error.response.data.message); + + case 500: + throw new Error(error.response.data.message); + + default: + throw new Error("Unknown Error"); + } + }, ); axiosInstance.interceptors.request.use((config) => { From a94890f7ba05ba34e464cd73e51c1d34211a490a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Thu, 14 Sep 2023 01:11:08 +0900 Subject: [PATCH 03/36] =?UTF-8?q?feat:=20=ED=86=A0=ED=81=B0=EC=9D=B4=20?= =?UTF-8?q?=ED=95=84=EC=9A=94=EC=97=86=EC=9D=84=20=EB=95=8C=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=A0=20axios=20instance=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jurumarble/src/lib/apis/http/base.ts | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 apps/jurumarble/src/lib/apis/http/base.ts diff --git a/apps/jurumarble/src/lib/apis/http/base.ts b/apps/jurumarble/src/lib/apis/http/base.ts new file mode 100644 index 00000000..5b986ff5 --- /dev/null +++ b/apps/jurumarble/src/lib/apis/http/base.ts @@ -0,0 +1,8 @@ +import axios from "axios"; +import { SERVER_URL } from "lib/constants"; + +const axiosInstance = axios.create({ + baseURL: SERVER_URL, +}); + +export const baseApi = axiosInstance; From b0bdc47b6842cdada0f13468640c71d9daa0bdbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Thu, 14 Sep 2023 01:11:33 +0900 Subject: [PATCH 04/36] =?UTF-8?q?chore:=20http=20=ED=8F=B4=EB=8D=94=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jurumarble/src/lib/apis/bookmark.ts | 2 +- apps/jurumarble/src/lib/apis/common.ts | 2 +- apps/jurumarble/src/lib/apis/restaurant.ts | 2 +- apps/jurumarble/src/lib/apis/vote.ts | 69 +++++++++++++++++++++- 4 files changed, 70 insertions(+), 5 deletions(-) diff --git a/apps/jurumarble/src/lib/apis/bookmark.ts b/apps/jurumarble/src/lib/apis/bookmark.ts index 413a5199..b34aaf2d 100644 --- a/apps/jurumarble/src/lib/apis/bookmark.ts +++ b/apps/jurumarble/src/lib/apis/bookmark.ts @@ -1,4 +1,4 @@ -import { http } from "./http"; +import { http } from "./http/http"; export const postBookmarkAPI = async (voteId: number) => { const response = await http.post(`api/votes/${voteId}/bookmark`, { voteId }); diff --git a/apps/jurumarble/src/lib/apis/common.ts b/apps/jurumarble/src/lib/apis/common.ts index f5bded25..93f1e681 100644 --- a/apps/jurumarble/src/lib/apis/common.ts +++ b/apps/jurumarble/src/lib/apis/common.ts @@ -1,4 +1,4 @@ -import { http } from "./http"; +import { http } from "./http/http"; export interface postVoteResponse { imageUrl: string; diff --git a/apps/jurumarble/src/lib/apis/restaurant.ts b/apps/jurumarble/src/lib/apis/restaurant.ts index 06c51b62..29d3a3f2 100644 --- a/apps/jurumarble/src/lib/apis/restaurant.ts +++ b/apps/jurumarble/src/lib/apis/restaurant.ts @@ -1,5 +1,5 @@ import { SERVER_URL } from "lib/constants"; -import { http } from "./http"; +import { http } from "./http/http"; interface GetRestaurantRequest { voteId: number; diff --git a/apps/jurumarble/src/lib/apis/vote.ts b/apps/jurumarble/src/lib/apis/vote.ts index 00cb12c5..5c8a4f7c 100644 --- a/apps/jurumarble/src/lib/apis/vote.ts +++ b/apps/jurumarble/src/lib/apis/vote.ts @@ -1,5 +1,5 @@ -import axios from "axios"; import { SERVER_URL } from "lib/constants"; +import { baseApi } from "./http/base"; export interface GetVoteListRequest { keyword?: string; @@ -34,7 +34,7 @@ interface GetVoteListResponse { } export const getVoteListAPI = async ({ page, size, sortBy, keyword }: GetVoteListRequest) => { - const response = await axios.get(`${SERVER_URL}api/votes`, { + const response = await baseApi.get("api/votes", { params: { page, size, @@ -133,3 +133,68 @@ export const postDrinkVoteAPI = async (voteInfo: PostDrinkVoteRequest) => { const res = await response.json(); return res.data; }; + +export type SortBy = "ByTime" | "ByName" | "ByPopularity"; + +export interface GetVoteDrinkListRequest { + page: number; + size: number; + keyword?: string; + region?: string; + sortBy: SortBy; +} + +interface Pageable { + sort: Sort; + pageNumber: number; + pageSize: number; + offset: number; + paged: boolean; + unpaged: boolean; +} + +interface Sort { + sorted: boolean; + unsorted: boolean; + empty: boolean; +} + +interface Content { + voteId: number; + postedUserId: number; + title: string; + detail?: any; + filteredGender?: any; + filteredAge?: any; + filteredMbti?: any; + votedCount?: any; + voteType: string; + imageA: string; + imageB: string; + titleA: string; + titleB: string; + region: string; +} + +interface GetVotetDrinkListResponse { + voteSlice: { + content: Content[]; + pageable: Pageable; + sort: Sort; + first: boolean; + last: boolean; + number: number; + numberOfElements: number; + size: number; + empty: boolean; + }; +} + +export const getVoteDrinkList = async (params: GetVoteDrinkListRequest) => { + const response = await baseApi.get("api/votes/drinks", { + params: { + ...params, + }, + }); + return response.data.voteSlice; +}; From 3148c91f5fbd0359e829b7c8b59dd4d5c9e366d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Thu, 14 Sep 2023 01:44:11 +0900 Subject: [PATCH 05/36] =?UTF-8?q?refactor:=20post=EB=BF=90=EB=A7=8C=20?= =?UTF-8?q?=EC=95=84=EB=8B=88=EB=9D=BC=20get=EC=9D=98=20=EC=97=AD=ED=95=A0?= =?UTF-8?q?=EB=8F=84=20=ED=95=98=EA=B3=A0=20=EC=9E=88=EC=9C=BC=EB=AF=80?= =?UTF-8?q?=EB=A1=9C=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jurumarble/src/app/vote/page.tsx | 4 +-- .../src/services/useBookmarkService.ts | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 apps/jurumarble/src/services/useBookmarkService.ts diff --git a/apps/jurumarble/src/app/vote/page.tsx b/apps/jurumarble/src/app/vote/page.tsx index 989d3624..2486e0e8 100644 --- a/apps/jurumarble/src/app/vote/page.tsx +++ b/apps/jurumarble/src/app/vote/page.tsx @@ -11,10 +11,10 @@ import SvgIcDetail from "src/assets/icons/components/IcDetail"; import styled, { css } from "styled-components"; import useFlipAnimation from "./hooks/useFlipAnimation"; import useInfiniteMainListService from "./post/services/useGetVoteListService"; -import usePostBookmarkService from "./post/services/useBookmarkService"; import ChipContainer from "./[id]/components/ChipContainer"; import VoteDescription from "./[id]/components/VoteDescription"; import Path from "lib/Path"; +import useBookmarkService from "services/useBookmarkService"; export type Drag = "up" | "down" | null; @@ -37,7 +37,7 @@ function VoteHomePage() { const { title, imageA, imageB, titleA, titleB, detail, voteId, region } = mainVoteList[nowShowing] || {}; - const { mutateBookMark, bookMarkCheckQuery } = usePostBookmarkService(voteId); + const { mutateBookMark, bookMarkCheckQuery } = useBookmarkService(voteId); const { data: bookmarkCheck } = bookMarkCheckQuery; diff --git a/apps/jurumarble/src/services/useBookmarkService.ts b/apps/jurumarble/src/services/useBookmarkService.ts new file mode 100644 index 00000000..100aa1b9 --- /dev/null +++ b/apps/jurumarble/src/services/useBookmarkService.ts @@ -0,0 +1,33 @@ +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { getBookMarkCheckAPI, postBookmarkAPI } from "lib/apis/bookmark"; +import Path from "lib/Path"; +import { queryKeys, reactQueryKeys } from "lib/queryKeys"; +import { useRouter } from "next/navigation"; +import { toast } from "react-toastify"; + +export default function useBookmarkService(voteId: number) { + const queryClient = useQueryClient(); + + const bookMarkCheckQuery = useQuery( + reactQueryKeys.bookmarkCheck(), + () => getBookMarkCheckAPI(voteId), + { + enabled: !!voteId, + }, + ); + + const router = useRouter(); + const { mutate: mutateBookMark } = useMutation(() => postBookmarkAPI(voteId), { + onSuccess: () => { + queryClient.invalidateQueries([queryKeys.BOOKMARK_CHECK]); + toast("북마크에서 해제되었어요"); + }, + onError: () => { + if (confirm("로그인이 필요한 서비스입니다.")) { + router.push(Path.VOTE_HOME); + } + }, + }); + + return { mutateBookMark, bookMarkCheckQuery }; +} From cde66b34ff850d58c8d68f422c851f3a4360d8f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:33:50 +0900 Subject: [PATCH 06/36] =?UTF-8?q?feat:=20=EC=99=B8=EB=B6=80=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=EB=A5=BC=20=ED=97=88=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jurumarble/next.config.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/jurumarble/next.config.js b/apps/jurumarble/next.config.js index ac3ab48f..d4836953 100644 --- a/apps/jurumarble/next.config.js +++ b/apps/jurumarble/next.config.js @@ -5,6 +5,9 @@ const nextConfig = { styledComponents: true, }, transpilePackages: ["@monorepo/ui, @monorepo/hooks"], + images: { + domains: ["shopping-phinf.pstatic.net"], + }, }; module.exports = nextConfig; From c49465a5af81c1db80b641b8a783e7a2007d79aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:34:42 +0900 Subject: [PATCH 07/36] =?UTF-8?q?chore:=20hooks=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=EC=97=90=20peerDependency=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/hooks/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/hooks/package.json b/packages/hooks/package.json index ddb5eaac..59054649 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -6,12 +6,12 @@ "license": "ISC", "version": "0.1.0", "main": "index.ts", - "dependencies": { - "react": "^18.2.0" - }, "devDependencies": { "@types/node": "20.5.7", "@types/react": "18.2.21", "typescript": "4.9.3" + }, + "peerDependencies": { + "react": "^18.2.0" } } From 17c3288c07d84b6869137fdffd7688502f3c6f27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:35:31 +0900 Subject: [PATCH 08/36] =?UTF-8?q?feat:=20hooks=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=EC=97=90=20intersection=20observer=20=ED=9B=85=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/hooks/src/useIntersectionObserver.ts | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 packages/hooks/src/useIntersectionObserver.ts diff --git a/packages/hooks/src/useIntersectionObserver.ts b/packages/hooks/src/useIntersectionObserver.ts new file mode 100644 index 00000000..f41f153d --- /dev/null +++ b/packages/hooks/src/useIntersectionObserver.ts @@ -0,0 +1,33 @@ +import { useCallback, useEffect, useRef, useState } from "react"; + +type Result = [(node: T | null) => void]; + +export default function useIntersectionObserver( + callback: IntersectionObserverCallback, + options?: IntersectionObserverInit, +): Result { + const [target, setTarget] = useState(null); + const observer = useRef(null); + + const subscribe = useCallback( + (node: T | null) => { + if (node) { + observer.current?.observe(node); + setTarget(node); + } + }, + [observer.current], + ); + + useEffect(() => { + observer.current = new IntersectionObserver(callback, options); + subscribe(target); + + return () => { + observer.current?.disconnect(); + observer.current = null; + }; + }, [callback, options]); + + return [subscribe]; +} From 8223ac40799b8c713b8f48d4f7d0515071c67b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:36:08 +0900 Subject: [PATCH 09/36] =?UTF-8?q?feat:=20hook=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=EC=97=90=20infinite=20scroll=20=ED=9B=85=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/hooks/src/index.ts | 2 ++ packages/hooks/src/useInfiniteScroll.ts | 33 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 packages/hooks/src/useInfiniteScroll.ts diff --git a/packages/hooks/src/index.ts b/packages/hooks/src/index.ts index bf5f3e08..42ce3f79 100644 --- a/packages/hooks/src/index.ts +++ b/packages/hooks/src/index.ts @@ -1,3 +1,5 @@ export { default as useToggle } from "./useToggle"; export { default as useOutsideClick } from "./useOutsideClick"; export { default as useDebounce } from "./useDebounce"; +export { default as useInfiniteScroll } from "./useInfiniteScroll"; +export { default as useIntersectionObserver } from "./useIntersectionObserver"; diff --git a/packages/hooks/src/useInfiniteScroll.ts b/packages/hooks/src/useInfiniteScroll.ts new file mode 100644 index 00000000..4384775b --- /dev/null +++ b/packages/hooks/src/useInfiniteScroll.ts @@ -0,0 +1,33 @@ +import { useCallback } from "react"; +import useIntersectionObserver from "./useIntersectionObserver"; + +/** + * 무한 스크롤에 사용하는 hooks + * + * ### 예제 + * ```tsx + * const [subscribe] = useInfiniteScroll(onLoadMore, { + * rootMargin: '100px', + * }); + * ... + * return ( + *
+ * ... + * ``` + */ +export default function useInfiniteScroll( + onLoadMore: () => unknown, + options?: IntersectionObserverInit, +) { + const subscriber = useCallback( + ([entry]: IntersectionObserverEntry[]) => { + if (!entry?.isIntersecting) { + return; + } + onLoadMore(); + }, + [onLoadMore], + ); + + return useIntersectionObserver(subscriber, options); +} From 72bf71c7e95118bc186db9d07c823a74d465af5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:36:40 +0900 Subject: [PATCH 10/36] =?UTF-8?q?feat:=20=EA=B3=B5=ED=86=B5=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jurumarble/src/types/common.ts | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/jurumarble/src/types/common.ts diff --git a/apps/jurumarble/src/types/common.ts b/apps/jurumarble/src/types/common.ts new file mode 100644 index 00000000..8204566c --- /dev/null +++ b/apps/jurumarble/src/types/common.ts @@ -0,0 +1 @@ +export type SortType = "ByTime" | "ByName" | "ByPopularity"; From 2c4ad0b6ed950d4920ed0f36097aeacfa33746fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:43:26 +0900 Subject: [PATCH 11/36] =?UTF-8?q?refactor:=20post=EB=BF=90=EB=A7=8C=20?= =?UTF-8?q?=EC=95=84=EB=8B=88=EB=9D=BC=20get=EC=9D=98=20=EC=97=AD=ED=95=A0?= =?UTF-8?q?=EB=8F=84=20=ED=95=98=EA=B3=A0=20=EC=9E=88=EC=9C=BC=EB=AF=80?= =?UTF-8?q?=EB=A1=9C=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vote/post/services/useBookmarkService.ts | 33 ------------------- 1 file changed, 33 deletions(-) delete mode 100644 apps/jurumarble/src/app/vote/post/services/useBookmarkService.ts diff --git a/apps/jurumarble/src/app/vote/post/services/useBookmarkService.ts b/apps/jurumarble/src/app/vote/post/services/useBookmarkService.ts deleted file mode 100644 index 429c46d6..00000000 --- a/apps/jurumarble/src/app/vote/post/services/useBookmarkService.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { getBookMarkCheckAPI, postBookmarkAPI } from "lib/apis/bookmark"; -import Path from "lib/Path"; -import { queryKeys, reactQueryKeys } from "lib/queryKeys"; -import { useRouter } from "next/navigation"; -import { toast } from "react-toastify"; - -export default function usePostBookmarkService(voteId: number) { - const queryClient = useQueryClient(); - - const bookMarkCheckQuery = useQuery( - reactQueryKeys.bookmarkCheck(), - () => getBookMarkCheckAPI(voteId), - { - enabled: !!voteId, - }, - ); - - const router = useRouter(); - const { mutate: mutateBookMark } = useMutation(() => postBookmarkAPI(voteId), { - onSuccess: () => { - queryClient.invalidateQueries([queryKeys.BOOKMARK_CHECK]); - toast("북마크에서 해제되었어요"); - }, - onError: () => { - if (confirm("로그인이 필요한 서비스입니다.")) { - router.push(Path.VOTE_HOME); - } - }, - }); - - return { mutateBookMark, bookMarkCheckQuery }; -} From bd58da36c51dbcee05aedb6c0f4322174d9f1b04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:44:50 +0900 Subject: [PATCH 12/36] =?UTF-8?q?feat:=20=EC=A0=84=ED=86=B5=EC=A3=BC=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EA=B0=80=EC=A0=B8?= =?UTF-8?q?=EC=98=A4=EB=8A=94=20api=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jurumarble/src/lib/apis/drink.ts | 62 +++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 apps/jurumarble/src/lib/apis/drink.ts diff --git a/apps/jurumarble/src/lib/apis/drink.ts b/apps/jurumarble/src/lib/apis/drink.ts new file mode 100644 index 00000000..0e917a11 --- /dev/null +++ b/apps/jurumarble/src/lib/apis/drink.ts @@ -0,0 +1,62 @@ +import { SortType } from "src/types/common"; +import { baseApi } from "./http/base"; + +export interface GetDrinkListRequest { + page: number; + size: number; + keyword?: string; + region?: string; + sortBy: SortType; +} + +interface GetDrinkListResponse { + sort: Sort; + first: boolean; + last: boolean; + number: number; + numberOfElements: number; + pageable: Pageable; + size: number; + content: DrinkInfo[]; + empty: boolean; +} + +export interface DrinkInfo { + id: number; + name: string; + type: string; + productName: string; + alcoholicBeverage: string; + rawMaterial: string; + capacity: string; + manufactureAddress: string; + region: string; + price: string; + image: string; + latitude: number; + longitude: number; + enjoyCount: number; +} + +interface Pageable { + sort: Sort; + pageNumber: number; + pageSize: number; + paged: boolean; + unpaged: boolean; + offset: number; +} + +interface Sort { + sorted: boolean; + unsorted: boolean; + empty: boolean; +} +export const getDrinkList = async (params: GetDrinkListRequest) => { + const response = await baseApi.get("api/drinks", { + params: { + ...params, + }, + }); + return response.data; +}; From 3d818669ba9c8b28b3a001b330e3b54b0d977ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:45:48 +0900 Subject: [PATCH 13/36] =?UTF-8?q?refactor:=20=ED=83=80=EC=9E=85=EC=9D=98?= =?UTF-8?q?=20=EC=9D=91=EC=A7=91=EB=8F=84=EB=A5=BC=20=EB=86=92=EC=9D=B4?= =?UTF-8?q?=EA=B8=B0=20=EC=9C=84=ED=95=B4=20=EA=B3=B5=ED=86=B5=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jurumarble/src/lib/apis/vote.ts | 32 +++++++--------------------- 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/apps/jurumarble/src/lib/apis/vote.ts b/apps/jurumarble/src/lib/apis/vote.ts index 5c8a4f7c..41eb57dc 100644 --- a/apps/jurumarble/src/lib/apis/vote.ts +++ b/apps/jurumarble/src/lib/apis/vote.ts @@ -1,14 +1,17 @@ import { SERVER_URL } from "lib/constants"; +import { SortType } from "src/types/common"; import { baseApi } from "./http/base"; +type VoteListSortType = Omit; + export interface GetVoteListRequest { keyword?: string; - sortBy: "ByTime" | "ByPopularity"; + sortBy: VoteListSortType; page: number; size: number; } -interface Vote { +export interface Vote { voteId: number; postedUserId: number; title: string; @@ -134,14 +137,12 @@ export const postDrinkVoteAPI = async (voteInfo: PostDrinkVoteRequest) => { return res.data; }; -export type SortBy = "ByTime" | "ByName" | "ByPopularity"; - export interface GetVoteDrinkListRequest { page: number; size: number; keyword?: string; region?: string; - sortBy: SortBy; + sortBy: string; } interface Pageable { @@ -159,26 +160,9 @@ interface Sort { empty: boolean; } -interface Content { - voteId: number; - postedUserId: number; - title: string; - detail?: any; - filteredGender?: any; - filteredAge?: any; - filteredMbti?: any; - votedCount?: any; - voteType: string; - imageA: string; - imageB: string; - titleA: string; - titleB: string; - region: string; -} - -interface GetVotetDrinkListResponse { +export interface GetVotetDrinkListResponse { voteSlice: { - content: Content[]; + content: Vote[]; pageable: Pageable; sort: Sort; first: boolean; From 8668a1e663370c62a6d1539411edc6d23d220e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:46:23 +0900 Subject: [PATCH 14/36] =?UTF-8?q?feat:=20=EC=A0=84=ED=86=B5=EC=A3=BC=20?= =?UTF-8?q?=EC=9D=B8=ED=8F=AC=20=ED=8E=98=EC=9D=B4=EC=A7=80=20url=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jurumarble/src/lib/Path.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/jurumarble/src/lib/Path.ts b/apps/jurumarble/src/lib/Path.ts index e4aa5c8a..dd227db0 100644 --- a/apps/jurumarble/src/lib/Path.ts +++ b/apps/jurumarble/src/lib/Path.ts @@ -18,6 +18,7 @@ const Path = { MAIN_PAGE: "/", VOTE_DETAIL_PAGE: "/detail", SEARCH_PAGE: "/search", + DRINK_INFO_PAGE: "/drink-info", } as const; export default Path; From 14fc158847e6e42a2a272e2761d9a51cae50b992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:49:09 +0900 Subject: [PATCH 15/36] =?UTF-8?q?feat:=20=EC=A0=95=EB=A0=AC=20=EC=98=B5?= =?UTF-8?q?=EC=85=98=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jurumarble/src/lib/constants.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/apps/jurumarble/src/lib/constants.ts b/apps/jurumarble/src/lib/constants.ts index e1a71dce..e0d31541 100644 --- a/apps/jurumarble/src/lib/constants.ts +++ b/apps/jurumarble/src/lib/constants.ts @@ -14,6 +14,10 @@ export const NAVER_LOGIN_REDIRECT_URL = ? `http://localhost:3000/${Path.NAVER_LOGIN_PROCESS}` : `${CLIENT_URL}${Path.NAVER_LOGIN_PROCESS}`; +/** + * @Todo type으로 사용할 수 있는 방법 알아보기 + */ + export const REGION_LIST = [ { value: "SEOUL", label: "서울" }, { value: "INCHEON", label: "인천" }, @@ -33,3 +37,9 @@ export const REGION_LIST = [ { value: "JEONNAM", label: "전라남도" }, { value: "JEJU", label: "제주" }, ]; + +export const SORT_LIST = [ + { value: "ByName", label: "이름순" }, + { value: "ByPopularity", label: "인기순" }, + { value: "ByTime", label: "최신순" }, +]; From ff9c8b29ec4d36e4fcb5f93417483583abe66237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:50:01 +0900 Subject: [PATCH 16/36] =?UTF-8?q?feat:=20=EC=A7=80=EC=97=AD=EB=AA=85?= =?UTF-8?q?=EA=B3=BC=20=EB=AA=87=EB=AA=85=EC=9D=B4=20=EC=A6=90=EA=B2=BC?= =?UTF-8?q?=EB=8A=94=EC=A7=80=EB=A5=BC=20=EB=B3=B4=EC=97=AC=EC=A3=BC?= =?UTF-8?q?=EB=8A=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jurumarble/src/components/Chip.tsx | 38 +++++++++++++++++++ .../jurumarble/src/components/button/Chip.tsx | 8 ---- 2 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 apps/jurumarble/src/components/Chip.tsx delete mode 100644 apps/jurumarble/src/components/button/Chip.tsx diff --git a/apps/jurumarble/src/components/Chip.tsx b/apps/jurumarble/src/components/Chip.tsx new file mode 100644 index 00000000..140a8c07 --- /dev/null +++ b/apps/jurumarble/src/components/Chip.tsx @@ -0,0 +1,38 @@ +import styled, { css } from "styled-components"; + +interface Props { + variant: "region" | "numberOfParticipants"; + children: React.ReactNode; +} + +type variant = Pick; + +function Chip({ variant, children }: Props) { + return {children}; +} + +const variantStyles = { + region: css` + ${({ theme }) => css` + background-color: ${theme.colors.main_02}; + color: ${theme.colors.main_01}; + `} + `, + numberOfParticipants: css` + ${({ theme }) => css` + background-color: ${theme.colors.bg_01}; + color: ${theme.colors.black_02}; + `} + `, +}; + +const Wrapper = styled.div` + ${({ theme, variant }) => css` + ${variant && variantStyles[variant]}; + ${theme.typography.caption} + padding: 10px 8px; + border-radius: 4px; + `} +`; + +export default Chip; diff --git a/apps/jurumarble/src/components/button/Chip.tsx b/apps/jurumarble/src/components/button/Chip.tsx deleted file mode 100644 index cf6b729f..00000000 --- a/apps/jurumarble/src/components/button/Chip.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import React from "react"; - -// TODO: Chip 컴포넌트 구현 -function Chip() { - return
Chip
; -} - -export default Chip; From a2a9e6751307d6fd56500a184c21a1049e629d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:50:49 +0900 Subject: [PATCH 17/36] =?UTF-8?q?feat:=20=EC=A3=BC=EB=A3=A8=EB=A7=88?= =?UTF-8?q?=EB=B8=94=EC=9D=98=20=EB=94=94=EC=9E=90=EC=9D=B8=EC=97=90=20?= =?UTF-8?q?=EB=A7=9E=EA=B2=8C=20select=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jurumarble/src/components/selectBox/Option.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/jurumarble/src/components/selectBox/Option.tsx b/apps/jurumarble/src/components/selectBox/Option.tsx index fd69fb51..fe5a66e9 100644 --- a/apps/jurumarble/src/components/selectBox/Option.tsx +++ b/apps/jurumarble/src/components/selectBox/Option.tsx @@ -14,7 +14,9 @@ function Option({ label, onChangeSelectedOption }: Props) { } const Li = styled.li` - padding: 14px 34px; + display: flex; + align-items: center; + justify-content: center; `; export default Option; From 8b68fc5c3e7361aebf3204afee80486512692fd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:52:15 +0900 Subject: [PATCH 18/36] =?UTF-8?q?feat:=20search=20input=EC=97=90=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20=EA=B4=80=EB=A6=AC=EB=A5=BC=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jurumarble/src/components/SearchInput.tsx | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/apps/jurumarble/src/components/SearchInput.tsx b/apps/jurumarble/src/components/SearchInput.tsx index 25827a28..623da02e 100644 --- a/apps/jurumarble/src/components/SearchInput.tsx +++ b/apps/jurumarble/src/components/SearchInput.tsx @@ -1,25 +1,34 @@ import { Button } from "components/button"; import { Input } from "components/input"; +import { SvgIcX } from "src/assets/icons/components"; import SvgIcSearch from "src/assets/icons/components/IcSearch"; import styled, { css, useTheme } from "styled-components"; interface Props { + value: string; + onChange: (e: React.ChangeEvent) => void; placeholder?: string; } -function SearchInput({ placeholder }: Props) { +function SearchInput({ value, onChange, placeholder }: Props) { const theme = useTheme(); return ( - + + {/* */} ); } -const Search = styled.div` +const Search = styled.form` display: flex; margin-top: 8px; width: 100%; From 65962961a71ef881aeeb6620b42e02579f085547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:55:01 +0900 Subject: [PATCH 19/36] =?UTF-8?q?feat:=20=EC=A0=84=ED=86=B5=EC=A3=BC=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90?= =?UTF-8?q?=EC=84=9C=EB=8F=84=20=EC=82=AC=EC=9A=A9=ED=95=A0=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8F=84=EB=A1=9D=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vote/post/components/DrinkSearchModal.tsx | 4 +- .../vote/post => }/components/DrinkItem.tsx | 56 +++++++++++-------- 2 files changed, 35 insertions(+), 25 deletions(-) rename apps/jurumarble/src/{app/vote/post => }/components/DrinkItem.tsx (59%) diff --git a/apps/jurumarble/src/app/vote/post/components/DrinkSearchModal.tsx b/apps/jurumarble/src/app/vote/post/components/DrinkSearchModal.tsx index ee9bd230..c96bb560 100644 --- a/apps/jurumarble/src/app/vote/post/components/DrinkSearchModal.tsx +++ b/apps/jurumarble/src/app/vote/post/components/DrinkSearchModal.tsx @@ -7,10 +7,10 @@ import { useState } from "react"; import SvgIcX from "src/assets/icons/components/IcX"; import styled, { css } from "styled-components"; import useUpdateSelectedDrinkList from "../hooks/useUpdateSelectedDrinkList"; -import DrinkItem from "./DrinkItem"; import SearchInput from "../../../../components/SearchInput"; import RegionSelect from "./RegionSelect"; import SelectedDrinkChip from "./SelectedDrinkChip"; +import DrinkItem from "components/DrinkItem"; interface Props { onToggleDrinkSearchModal: () => void; @@ -71,7 +71,7 @@ function DrinkSearchModal({ onToggleDrinkSearchModal }: Props) { {TEMP_LIST.map(({ drinkName, manufacturer }) => ( ) => void; - selectedDrinkList: string[]; + onClickAddDrink?: (e: React.MouseEvent) => void; + selectedDrinkList?: string[]; } -function DrinkItem({ - staticImage, - drinkName = "제품명", - manufacturer = "제조사", - stamp, - onClickAddDrink, - selectedDrinkList, -}: Props) { +function DrinkItem({ drinkInfo, stamp, onClickAddDrink, selectedDrinkList }: Props) { + const { id, name, productName, image } = drinkInfo; + const { colors } = useTheme(); + + const router = useRouter(); + const onClickDrinkItem = () => { + router.push(`${Path.DRINK_INFO_PAGE}/${id}`); + }; + return ( - 임시 이미지 + 임시 이미지 - {drinkName} + {name} {stamp && ( )} - {manufacturer} - + {productName} + + 서울 + 213명이 즐겼어요 + ); } -const Container = styled.button<{ selected: boolean }>` +const Container = styled.button<{ selected: boolean | undefined }>` display: flex; box-shadow: 0px 2px 8px 0px rgba(235, 235, 235, 0.4), 0px 8px 20px 0px rgba(235, 235, 235, 0.4); height: 120px; @@ -104,6 +110,10 @@ const ManufacturerName = styled.span` `} `; -const ChipContainer = styled.div``; +const ChipContainer = styled.div` + display: flex; + margin-top: 13px; + gap: 4px; +`; export default DrinkItem; From 6f8ab6171e0255ecfcfb46c6ac8e661d6f65ab63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:55:58 +0900 Subject: [PATCH 20/36] =?UTF-8?q?feat:=20=EA=B2=80=EC=83=89=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EC=97=90=EC=84=9C=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EC=A0=84=ED=86=B5=EC=A3=BC=20=ED=88=AC?= =?UTF-8?q?=ED=91=9C=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/search/components/DrinkVoteItem.tsx | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 apps/jurumarble/src/app/search/components/DrinkVoteItem.tsx diff --git a/apps/jurumarble/src/app/search/components/DrinkVoteItem.tsx b/apps/jurumarble/src/app/search/components/DrinkVoteItem.tsx new file mode 100644 index 00000000..01387d57 --- /dev/null +++ b/apps/jurumarble/src/app/search/components/DrinkVoteItem.tsx @@ -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 ( + + + + + ); +} + +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; From dece2a5b8c2945dbded1006b2741eccd517b9463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:57:23 +0900 Subject: [PATCH 21/36] =?UTF-8?q?feat:=20=EC=A0=84=ED=86=B5=EC=A3=BC=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EB=AC=B4=ED=95=9C=20?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A1=A4=EB=A1=9C=20=EA=B0=80=EC=A0=B8?= =?UTF-8?q?=EC=98=A4=EB=8A=94=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/search/services/useDrinkService.ts | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 apps/jurumarble/src/app/search/services/useDrinkService.ts diff --git a/apps/jurumarble/src/app/search/services/useDrinkService.ts b/apps/jurumarble/src/app/search/services/useDrinkService.ts new file mode 100644 index 00000000..39d7cad9 --- /dev/null +++ b/apps/jurumarble/src/app/search/services/useDrinkService.ts @@ -0,0 +1,34 @@ +import { useInfiniteQuery } from "@tanstack/react-query"; +import { getDrinkList } from "lib/apis/drink"; +import { queryKeys } from "lib/queryKeys"; + +type SearchDrinkServiceProps = Exclude[0], undefined>; + +const getQueryKey = (params: SearchDrinkServiceProps) => [ + queryKeys.SEARCH_DRINK_LIST, + { ...params }, +]; + +export default function useSearchDrinkService(params: SearchDrinkServiceProps) { + const { data, fetchNextPage, hasNextPage } = useInfiniteQuery( + getQueryKey(params), + ({ pageParam }) => + getDrinkList({ + ...params, + page: pageParam?.page || params.page, + }), + { + getNextPageParam: ({ last, number }) => { + if (last) return undefined; + return { + page: number + 1, + }; + }, + keepPreviousData: true, + }, + ); + + const drinkList = data?.pages.flatMap((page) => page.content) ?? []; + + return { drinkList, fetchNextPage, hasNextPage }; +} From 17e4296a554fe38820e248aa8970890ca70140b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 01:57:46 +0900 Subject: [PATCH 22/36] =?UTF-8?q?feat:=20=EC=A0=84=ED=86=B5=EC=A3=BC=20?= =?UTF-8?q?=ED=88=AC=ED=91=9C=EB=A5=BC=20=EB=AC=B4=ED=95=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A1=A4=EB=A1=9C=20=EA=B0=80=EC=A0=B8=EC=98=A4?= =?UTF-8?q?=EB=8A=94=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../search/services/useVoteDrinkService.ts | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 apps/jurumarble/src/app/search/services/useVoteDrinkService.ts diff --git a/apps/jurumarble/src/app/search/services/useVoteDrinkService.ts b/apps/jurumarble/src/app/search/services/useVoteDrinkService.ts new file mode 100644 index 00000000..a4b75024 --- /dev/null +++ b/apps/jurumarble/src/app/search/services/useVoteDrinkService.ts @@ -0,0 +1,34 @@ +import { useInfiniteQuery } from "@tanstack/react-query"; +import { getVoteDrinkList } from "lib/apis/vote"; +import { queryKeys } from "lib/queryKeys"; + +type SearchVoteDrinkServiceProps = Exclude[0], undefined>; + +const getQueryKey = (params: SearchVoteDrinkServiceProps) => [ + queryKeys.SEARCH_VOTE_DRINK_LIST, + { ...params }, +]; + +export default function useVoteDrinkService(params: SearchVoteDrinkServiceProps) { + const { data, fetchNextPage, hasNextPage } = useInfiniteQuery( + getQueryKey(params), + ({ pageParam }) => + getVoteDrinkList({ + ...params, + page: pageParam?.page || params.page, + }), + { + getNextPageParam: ({ last, number }) => { + if (last) return undefined; + return { + page: number + 1, + }; + }, + keepPreviousData: true, + }, + ); + + const voteDrinkList = data?.pages.flatMap((page) => page.content) ?? []; + + return { voteDrinkList, fetchNextPage, hasNextPage }; +} From 6c8ee93d4bbf8874f4fb7f49e2bf59414fdbf381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 02:00:15 +0900 Subject: [PATCH 23/36] =?UTF-8?q?refactor:=20Chip=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/vote/[id]/components/ChipContainer.tsx | 18 +++--------------- .../[id]/components/SearchRestaurantModal.tsx | 7 +++---- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/apps/jurumarble/src/app/vote/[id]/components/ChipContainer.tsx b/apps/jurumarble/src/app/vote/[id]/components/ChipContainer.tsx index 5fab983e..da79a6bd 100644 --- a/apps/jurumarble/src/app/vote/[id]/components/ChipContainer.tsx +++ b/apps/jurumarble/src/app/vote/[id]/components/ChipContainer.tsx @@ -1,4 +1,5 @@ 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"; @@ -23,8 +24,8 @@ const ChipContainer = ({ date, description, title, region, mutateBookMark, isBoo <> - {region && {region}} - {/* 122명이 즐겼어요 */} + {region && {region}} + {/* 122명이 즐겼어요 */} {isBookmark ? ( @@ -86,19 +87,6 @@ const FlexRow = styled.div` gap: 8px; `; -const NormalTag = styled.div` - padding: 10px 8px; - ${({ theme }) => theme.typography.caption} - background-color: ${({ theme }) => theme.colors.bg_01}; - color: ${({ theme }) => theme.colors.black_01}; - border-radius: 4px; -`; - -const RegionTag = styled(NormalTag)` - background-color: ${({ theme }) => theme.colors.main_02}; - color: ${({ theme }) => theme.colors.main_01}; -`; - const Description = styled.div` padding-bottom: 20px; ${({ theme }) => theme.typography.body_long03} diff --git a/apps/jurumarble/src/app/vote/[id]/components/SearchRestaurantModal.tsx b/apps/jurumarble/src/app/vote/[id]/components/SearchRestaurantModal.tsx index 0848fe1b..3aaa84f7 100644 --- a/apps/jurumarble/src/app/vote/[id]/components/SearchRestaurantModal.tsx +++ b/apps/jurumarble/src/app/vote/[id]/components/SearchRestaurantModal.tsx @@ -1,14 +1,13 @@ "use client"; import { Button, ModalTemplate } from "components/index"; -import SearchInput from "components/SearchInput"; import VoteHeader from "components/VoteHeader"; -import { ThemeColors, transitions } from "lib/styles"; +import { transitions } from "lib/styles"; import Image from "next/image"; import { EmptyAImg } from "public/images"; import { useState } from "react"; import SvgIcX from "src/assets/icons/components/IcX"; -import styled, { css } from "styled-components"; +import styled, { css, DefaultTheme } from "styled-components"; import RestaurantItem from "./RestaurantItem"; interface Props { @@ -139,7 +138,7 @@ const FoodItem = styled.div` position: relative; `; -const ColorBox = styled.div<{ theme: ThemeColors; selected: boolean }>` +const ColorBox = styled.div<{ theme: DefaultTheme; selected: boolean }>` ${({ theme, selected }) => css` border-radius: 4px; From 4c18a9da696b83e235a7d845abb15f157145388c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 02:01:03 +0900 Subject: [PATCH 24/36] =?UTF-8?q?refactor:=20sort=20type=EC=97=90=20?= =?UTF-8?q?=EA=B3=B5=ED=86=B5=20=ED=83=80=EC=9E=85=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/app/vote/post/services/useGetVoteListService.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/jurumarble/src/app/vote/post/services/useGetVoteListService.tsx b/apps/jurumarble/src/app/vote/post/services/useGetVoteListService.tsx index ff2fdbce..a3b2651a 100644 --- a/apps/jurumarble/src/app/vote/post/services/useGetVoteListService.tsx +++ b/apps/jurumarble/src/app/vote/post/services/useGetVoteListService.tsx @@ -2,10 +2,13 @@ import { useInfiniteQuery } from "@tanstack/react-query"; import { getVoteListAPI } from "lib/apis/vote"; import { reactQueryKeys } from "lib/queryKeys"; import { useEffect, useMemo, useState } from "react"; +import { SortType } from "src/types/common"; + +type VoteListSortType = Omit; interface Props { size: number; - sortBy: "ByTime" | "ByPopularity"; + sortBy: VoteListSortType; keyword?: string; } From d079e1accd2c01c455cd6a3b49b247120d297b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 02:01:47 +0900 Subject: [PATCH 25/36] =?UTF-8?q?feat:=20=EC=A0=95=EB=A0=AC=20=EC=98=B5?= =?UTF-8?q?=EC=85=98=20select=20box=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/app/search/components/SortSelect.tsx | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 apps/jurumarble/src/app/search/components/SortSelect.tsx diff --git a/apps/jurumarble/src/app/search/components/SortSelect.tsx b/apps/jurumarble/src/app/search/components/SortSelect.tsx new file mode 100644 index 00000000..d9adee47 --- /dev/null +++ b/apps/jurumarble/src/app/search/components/SortSelect.tsx @@ -0,0 +1,59 @@ +import { 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; +} + +function SortSelect({ defaultOption, onChangeSortOption }: Props) { + const [isOpen, onToggleOpen] = useToggle(); + + return ( + + + + ); +} + +const SelectStyled = styled.span<{ isOpen: boolean }>` + ${({ theme, isOpen }) => css` + ${theme.typography.button01}; + color: ${theme.colors.black_03}; + width: 85px; + /* height: 40px; */ + .selected-label { + border: 1px solid ${theme.colors.line_01}; + border-radius: 8px; + padding: 10px 12px; + } + svg { + ${isOpen && "transform: rotateX( 180deg )"} + } + #select-list { + width: 100px; + height: 78px; + display: flex; + flex-direction: column; + align-items: center; + padding: 8px 0; + gap: 20px; + } + #indicator { + display: flex; + } + `} +`; + +export default SortSelect; From 2769a94d66c32f59cec5f1f19c2f436278a6ea3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 02:02:06 +0900 Subject: [PATCH 26/36] =?UTF-8?q?feat:=20=EC=A7=80=EC=97=AD=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=20select=20box=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../search/components/RegionSmallSelect.tsx | 62 +++++++++++++++++++ .../app/vote/post/components/RegionSelect.tsx | 3 + 2 files changed, 65 insertions(+) create mode 100644 apps/jurumarble/src/app/search/components/RegionSmallSelect.tsx diff --git a/apps/jurumarble/src/app/search/components/RegionSmallSelect.tsx b/apps/jurumarble/src/app/search/components/RegionSmallSelect.tsx new file mode 100644 index 00000000..6e2972aa --- /dev/null +++ b/apps/jurumarble/src/app/search/components/RegionSmallSelect.tsx @@ -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 ( + + + + ); +} + +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; diff --git a/apps/jurumarble/src/app/vote/post/components/RegionSelect.tsx b/apps/jurumarble/src/app/vote/post/components/RegionSelect.tsx index 78a70c14..2d2f27a7 100644 --- a/apps/jurumarble/src/app/vote/post/components/RegionSelect.tsx +++ b/apps/jurumarble/src/app/vote/post/components/RegionSelect.tsx @@ -51,6 +51,9 @@ const SelectStyled = styled.div<{ isOpen: boolean }>` left: 22px; width: 335px; height: 330px; + display: flex; + flex-direction: column; + gap: 20px; } li { display: flex; From b1fb8f5e9a189a81a7d3b88a4fc072fdc29993c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 02:02:56 +0900 Subject: [PATCH 27/36] =?UTF-8?q?fix:=20=EC=98=A4=ED=83=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jurumarble/src/app/vote/[id]/components/VoteDescription.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/jurumarble/src/app/vote/[id]/components/VoteDescription.tsx b/apps/jurumarble/src/app/vote/[id]/components/VoteDescription.tsx index 3930a0de..d9ecba5a 100644 --- a/apps/jurumarble/src/app/vote/[id]/components/VoteDescription.tsx +++ b/apps/jurumarble/src/app/vote/[id]/components/VoteDescription.tsx @@ -98,7 +98,7 @@ const Container = styled.div``; const ImageWrapper = styled.div` position: relative; display: flex; - width: 100%;z + width: 100%; height: 100%; gap: 9px; `; From f631c931fda8fe9f3c245257b36715ce83a657a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 02:03:25 +0900 Subject: [PATCH 28/36] =?UTF-8?q?feat:=20expand=20more=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=EC=BD=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assets/icons/components/IcExpandMore.tsx | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 apps/jurumarble/src/assets/icons/components/IcExpandMore.tsx diff --git a/apps/jurumarble/src/assets/icons/components/IcExpandMore.tsx b/apps/jurumarble/src/assets/icons/components/IcExpandMore.tsx new file mode 100644 index 00000000..cdd90dbf --- /dev/null +++ b/apps/jurumarble/src/assets/icons/components/IcExpandMore.tsx @@ -0,0 +1,33 @@ +import type { SVGProps } from "react"; +const SvgIcExpandMore = (props: SVGProps) => ( + + + + + + + + +); +export default SvgIcExpandMore; From d3de3537ccd74bf2084c2e31a74733c1e4c163f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 02:03:50 +0900 Subject: [PATCH 29/36] =?UTF-8?q?feat:=20=EC=BF=BC=EB=A6=AC=ED=82=A4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jurumarble/src/lib/queryKeys.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/jurumarble/src/lib/queryKeys.ts b/apps/jurumarble/src/lib/queryKeys.ts index c58217f1..34af1717 100644 --- a/apps/jurumarble/src/lib/queryKeys.ts +++ b/apps/jurumarble/src/lib/queryKeys.ts @@ -4,7 +4,8 @@ export const queryKeys = { USER_INFO: "userInfo" as const, VOTE_LIST: "voteList" as const, RESTAURANT_LIST: "restaurantList" as const, - DRINK_LIST: "drinkList" as const, + SEARCH_DRINK_LIST: "searchDrinkList" as const, + SEARCH_VOTE_DRINK_LIST: "searchVoteDrinkList" as const, }; export const reactQueryKeys = { @@ -14,5 +15,4 @@ export const reactQueryKeys = { userInfo: () => [queryKeys.USER_INFO], voteList: (params: any) => [queryKeys.VOTE_LIST, ...params], restaurantList: (params: any) => [queryKeys.RESTAURANT_LIST, ...params], - drinkList: (params: any) => [queryKeys.DRINK_LIST, ...params], }; From df6c448643ce153bfa369e5101eb787ec5ba14c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 02:04:37 +0900 Subject: [PATCH 30/36] =?UTF-8?q?feat:=20=EC=A0=84=ED=86=B5=EC=A3=BC=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/app/search/components/DrinkList.tsx | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 apps/jurumarble/src/app/search/components/DrinkList.tsx diff --git a/apps/jurumarble/src/app/search/components/DrinkList.tsx b/apps/jurumarble/src/app/search/components/DrinkList.tsx new file mode 100644 index 00000000..37cbcd2b --- /dev/null +++ b/apps/jurumarble/src/app/search/components/DrinkList.tsx @@ -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 ( + + {drinkList.map((drinkInfo) => ( + + ))} + {!isSelectedTab && ( + + 우리술 정보 더보기 + + )} + + ); +} + +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; From 326f06037978411721c43f593b7237ad702ce917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 02:04:49 +0900 Subject: [PATCH 31/36] =?UTF-8?q?feat:=20=EC=A0=84=ED=89=81=EC=A3=BC=20?= =?UTF-8?q?=ED=88=AC=ED=91=9C=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/search/components/DrinkVoteList.tsx | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 apps/jurumarble/src/app/search/components/DrinkVoteList.tsx diff --git a/apps/jurumarble/src/app/search/components/DrinkVoteList.tsx b/apps/jurumarble/src/app/search/components/DrinkVoteList.tsx new file mode 100644 index 00000000..4f105da1 --- /dev/null +++ b/apps/jurumarble/src/app/search/components/DrinkVoteList.tsx @@ -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 ( + + {voteDrinkList.map((voteDrink, index) => ( + + ))} + {!isSelectedTab && ( + + 우리술 투표 더보기 + + )} + + ); +} + +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; From bb4ac5a12f49090565b99a87e922581b2f0ce591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 02:05:45 +0900 Subject: [PATCH 32/36] =?UTF-8?q?feat:=20=EC=A0=84=ED=86=B5=EC=A3=BC=20?= =?UTF-8?q?=ED=88=AC=ED=91=9C=EC=97=90=EC=84=9C=20=EC=B9=A9=EC=9D=84=20?= =?UTF-8?q?=EB=B3=B4=EC=97=AC=EC=A3=BC=EB=8A=94=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/search/components/ChipContainer.tsx | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 apps/jurumarble/src/app/search/components/ChipContainer.tsx diff --git a/apps/jurumarble/src/app/search/components/ChipContainer.tsx b/apps/jurumarble/src/app/search/components/ChipContainer.tsx new file mode 100644 index 00000000..1ff0a1cb --- /dev/null +++ b/apps/jurumarble/src/app/search/components/ChipContainer.tsx @@ -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 ( + <> + + + {region && {region}} + 122명이 즐겼어요 + + + {isBookmark ? ( + mutateBookMark()} /> + ) : ( + mutateBookMark()} /> + )} + + + + {title} + {/* {date.slice(0, 10)} */} + + {date} + + ); +}; + +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; From d1664a06fb3a55581c02a0b717ea156b3faa520c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 02:06:14 +0900 Subject: [PATCH 33/36] =?UTF-8?q?feat:=20=EC=A0=84=ED=86=B5=EC=A3=BC=20?= =?UTF-8?q?=ED=88=AC=ED=91=9C=EC=97=90=EC=84=9C=20=ED=88=AC=ED=91=9C=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EB=B3=B4=EC=97=AC=EC=A3=BC?= =?UTF-8?q?=EB=8A=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/search/components/VoteDescription.tsx | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 apps/jurumarble/src/app/search/components/VoteDescription.tsx diff --git a/apps/jurumarble/src/app/search/components/VoteDescription.tsx b/apps/jurumarble/src/app/search/components/VoteDescription.tsx new file mode 100644 index 00000000..49f36059 --- /dev/null +++ b/apps/jurumarble/src/app/search/components/VoteDescription.tsx @@ -0,0 +1,43 @@ +import Image, { StaticImageData } from "next/image"; +import styled from "styled-components"; + +interface Props { + imageA: string | StaticImageData; + imageB: string | StaticImageData; +} + +function VoteDescription({ imageA, imageB }: Props) { + return ( + + + + A 이미지 + + + B 이미지 + + + + ); +} + +const Container = styled.div``; + +const ImageWrapper = styled.div` + position: relative; + display: flex; + width: 100%; + height: 100%; + gap: 9px; +`; +const LeftVote = styled.div` + position: relative; + width: 50%; + aspect-ratio: 1; + display: flex; + justify-content: center; +`; + +const RightVote = styled(LeftVote)``; + +export default VoteDescription; From f54f265e71e55b94c3f451c6fd5a96f03e7b14eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 02:06:55 +0900 Subject: [PATCH 34/36] =?UTF-8?q?feat:=20=EA=B2=80=EC=83=89=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jurumarble/src/app/search/page.tsx | 217 +++++++++++++++++++----- apps/jurumarble/tsconfig.json | 3 +- 2 files changed, 179 insertions(+), 41 deletions(-) diff --git a/apps/jurumarble/src/app/search/page.tsx b/apps/jurumarble/src/app/search/page.tsx index f18188b9..6c30ad1c 100644 --- a/apps/jurumarble/src/app/search/page.tsx +++ b/apps/jurumarble/src/app/search/page.tsx @@ -1,67 +1,204 @@ "use client"; import BottomBar from "components/BottomBar"; +import { Button } from "components/button"; +import SearchInput from "components/SearchInput"; +import useInput from "hooks/useInput"; import SvgIcPrev from "src/assets/icons/components/IcPrev"; -import SvgIcX from "src/assets/icons/components/IcX"; -import styled, { css } from "styled-components"; +import styled, { css, DefaultTheme } from "styled-components"; +import DrinkList from "./components/DrinkList"; +import DrinkVoteList from "./components/DrinkVoteList"; +import { useState } from "react"; +import { SORT_LIST } from "lib/constants"; +import SortSelect from "./components/SortSelect"; +import RegionSmallSelect from "./components/RegionSmallSelect"; + +const TAB_LIST = [ + { id: "total", name: "통합" }, + { id: "drinkInfo", name: "우리술 정보" }, + { id: "drinkVote", name: "우리술 투표" }, +]; function Search() { - return ( - - - + const { value: searchText, onChange: onChangeSearchText } = useInput({ + initialValue: "", + useDebounce: true, + }); + + const [selectedTab, setSelectedTab] = useState("total"); + const onClickSelectedTab = (e: React.MouseEvent) => { + setSelectedTab(e.currentTarget.value); + }; + + const [sortOption, setSortOption] = useState(SORT_LIST[1].value); + const onChangeSortOption = (value: string) => { + setSortOption(value); + }; - - - - - + const [regionOption, setRegionOption] = useState(""); + const onChangeRegionOption = (value: string) => { + setRegionOption(value); + }; + + const isSelectedTab = (tabName: string) => { + return selectedTab === tabName; + }; + + return ( + <> + + + + + + + {TAB_LIST.map(({ id, name }) => ( + + {name} + + ))} + + {!isSelectedTab("total") && ( + + + + + )} + {isSelectedTab("total") &&

우리술 정보

} + {isSelectedTab("drinkVote") ? ( + <> + ) : ( + <> + + {selectedTab === "total" && ( + + 우리술 정보 더보기 + + )} + + )} +
+ {isSelectedTab("total") && } + + {selectedTab === "drinkInfo" ? ( + <> + ) : ( + <> + {isSelectedTab("total") &&

우리술 투표

} + + {isSelectedTab("total") && ( + + 우리술 투표 더보기 + + )} + + )} +
-
+ ); } -const Container = styled.div` - height: 100vh; - overflow: hidden; +const TopSection = styled.section` + padding: 0 20px; `; const SearchBox = styled.div` - position: relative; - padding: 8px 20px; display: flex; align-items: center; - gap: 12px; - box-shadow: 0px 16px 32px 0px rgba(235, 235, 235, 0.6); + gap: 14px; `; -const SearchInput = styled.input` - flex: 1; - border-radius: 8px; - border: none; - padding: 12px; - &:focus { - outline: none; - } +const TabBox = styled.ul` + display: flex; + margin-top: 8px; +`; + +const DivideLine = styled.div` ${({ theme }) => css` - ${theme.typography.body02}; - background-color: ${theme.colors.bg_02}; - color: ${theme.colors.black_01}; - &::placeholder { - color: ${theme.colors.black_05}; - } + background-color: ${theme.colors.bg_01}; + height: 8px; `} `; -const ResetIconBox = styled.div` - position: absolute; - top: 0; - bottom: 0; - right: 32px; +const SelectedButton = styled.button<{ theme: DefaultTheme; selected: boolean }>` + ${({ theme, selected }) => + css` + ${theme.typography.body02}; + color: ${theme.colors.black_03}; + padding: 16.5px 12px; + + ${selected + ? css` + ${theme.typography.body01}; + color: ${theme.colors.black_01}; + border-bottom: 3px solid ${theme.colors.black_01}; + ` + : css` + display: flex; + `} + `} +`; + +const SelectContainer = styled.div` display: flex; - align-items: center; - justify-content: center; + margin-top: 40px; + gap: 4px; +`; + +const H2 = styled.h2` + ${({ theme }) => css` + ${theme.typography.headline02}; + color: ${theme.colors.black_01}; + margin-top: 40px; + `} +`; + +const MoreButton = styled(Button)` + ${({ theme }) => css` + ${theme.typography.body01} + margin: 24px 0 40px 0; + `}; +`; + +const BottomSection = styled.section` + padding: 0 20px 96px; + margin-top: 8px; // 64(BottomBar height) + 32(margin) = 96 + overflow: auto; `; export default Search; diff --git a/apps/jurumarble/tsconfig.json b/apps/jurumarble/tsconfig.json index 652da1fd..31ae73b9 100644 --- a/apps/jurumarble/tsconfig.json +++ b/apps/jurumarble/tsconfig.json @@ -18,7 +18,8 @@ "styles/*": ["./src/styles/*"], "lib/*": ["./src/lib/*"], "hooks/*": ["./src/hooks/*"], - "public/*": ["./public/*"] + "public/*": ["./public/*"], + "services/*": ["./src/services/*"] } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], From fba54f68ceaf6ede941102eda97889d5c18533f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 02:08:32 +0900 Subject: [PATCH 35/36] =?UTF-8?q?fix:=20=EC=83=88=EB=A1=9C=EC=9A=B4=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pnp.cjs | 24 +++++++++++++++++++----- yarn.lock | 3 ++- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/.pnp.cjs b/.pnp.cjs index a328e47e..b5be13c9 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -36,7 +36,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "ignorePatternData": "(^(?:\\\\.yarn\\\\/sdks(?:\\\\/(?!\\\\.{1,2}(?:\\\\/|$))(?:(?:(?!(?:^|\\\\/)\\\\.{1,2}(?:\\\\/|$)).)*?)|$))$)",\ "fallbackExclusionList": [\ ["@monorepo/chooz", ["workspace:apps/chooz"]],\ - ["@monorepo/hooks", ["workspace:packages/hooks"]],\ + ["@monorepo/hooks", ["virtual:040d27df013de8c2443d97cd34785bd6338b0d64a4a625937768b1a38353fca7b8404d53a1248b5c67570c2a031bc43d100149c15012f4485eb41e15d763240d#workspace:packages/hooks", "workspace:packages/hooks"]],\ ["@monorepo/jurumarble", ["workspace:apps/jurumarble"]],\ ["@monorepo/ui", ["workspace:packages/ui"]],\ ["monorepo", ["workspace:."]]\ @@ -4065,7 +4065,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./apps/chooz/",\ "packageDependencies": [\ ["@monorepo/chooz", "workspace:apps/chooz"],\ - ["@monorepo/hooks", "workspace:packages/hooks"],\ + ["@monorepo/hooks", "virtual:040d27df013de8c2443d97cd34785bd6338b0d64a4a625937768b1a38353fca7b8404d53a1248b5c67570c2a031bc43d100149c15012f4485eb41e15d763240d#workspace:packages/hooks"],\ ["@monorepo/ui", "workspace:packages/ui"],\ ["@next/font", "npm:13.4.19"],\ ["@svgr/cli", "npm:7.0.0"],\ @@ -4094,13 +4094,27 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]\ ]],\ ["@monorepo/hooks", [\ + ["virtual:040d27df013de8c2443d97cd34785bd6338b0d64a4a625937768b1a38353fca7b8404d53a1248b5c67570c2a031bc43d100149c15012f4485eb41e15d763240d#workspace:packages/hooks", {\ + "packageLocation": "./.yarn/__virtual__/@monorepo-hooks-virtual-9a9d2697d3/1/packages/hooks/",\ + "packageDependencies": [\ + ["@monorepo/hooks", "virtual:040d27df013de8c2443d97cd34785bd6338b0d64a4a625937768b1a38353fca7b8404d53a1248b5c67570c2a031bc43d100149c15012f4485eb41e15d763240d#workspace:packages/hooks"],\ + ["@types/node", "npm:20.5.7"],\ + ["@types/react", "npm:18.2.21"],\ + ["react", "npm:18.2.0"],\ + ["typescript", "patch:typescript@npm%3A4.9.3#~builtin::version=4.9.3&hash=d73830"]\ + ],\ + "packagePeers": [\ + "@types/react",\ + "react"\ + ],\ + "linkType": "SOFT"\ + }],\ ["workspace:packages/hooks", {\ "packageLocation": "./packages/hooks/",\ "packageDependencies": [\ ["@monorepo/hooks", "workspace:packages/hooks"],\ ["@types/node", "npm:20.5.7"],\ ["@types/react", "npm:18.2.21"],\ - ["react", "npm:18.2.0"],\ ["typescript", "patch:typescript@npm%3A4.9.3#~builtin::version=4.9.3&hash=d73830"]\ ],\ "linkType": "SOFT"\ @@ -4112,7 +4126,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageDependencies": [\ ["@monorepo/jurumarble", "workspace:apps/jurumarble"],\ ["@emotion/is-prop-valid", "npm:1.2.1"],\ - ["@monorepo/hooks", "workspace:packages/hooks"],\ + ["@monorepo/hooks", "virtual:040d27df013de8c2443d97cd34785bd6338b0d64a4a625937768b1a38353fca7b8404d53a1248b5c67570c2a031bc43d100149c15012f4485eb41e15d763240d#workspace:packages/hooks"],\ ["@svgr/cli", "npm:8.1.0"],\ ["@svgr/core", "npm:8.1.0"],\ ["@svgr/plugin-jsx", "virtual:f6fc21e1196a5e36ccf7110701b6043e0b913ea4ae1d1deb9368d1ebef4cb8924deb4e8e07aafc9678d844b070003814a4413e37134a210b07db139914fa76a4#npm:8.1.0"],\ @@ -4143,7 +4157,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./packages/ui/",\ "packageDependencies": [\ ["@monorepo/ui", "workspace:packages/ui"],\ - ["@monorepo/hooks", "workspace:packages/hooks"],\ + ["@monorepo/hooks", "virtual:040d27df013de8c2443d97cd34785bd6338b0d64a4a625937768b1a38353fca7b8404d53a1248b5c67570c2a031bc43d100149c15012f4485eb41e15d763240d#workspace:packages/hooks"],\ ["@types/node", "npm:20.5.7"],\ ["@types/react", "npm:18.2.21"],\ ["@types/styled-components", "npm:5.1.26"],\ diff --git a/yarn.lock b/yarn.lock index 1fe479fe..c66d2aeb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1585,8 +1585,9 @@ __metadata: dependencies: "@types/node": 20.5.7 "@types/react": 18.2.21 - react: ^18.2.0 typescript: 4.9.3 + peerDependencies: + react: ^18.2.0 languageName: unknown linkType: soft From 627c1b36cd6d0ef052bd3fab1039917fbb3f264f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8C=E1=85=A2=E1=84=92=E1=85=A1?= Date: Fri, 15 Sep 2023 02:11:30 +0900 Subject: [PATCH 36/36] =?UTF-8?q?fix:=20=EC=9D=8C=EC=8B=9D=EC=A0=90=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=AA=A8=EB=8B=AC=20=EC=9E=84=EC=8B=9C=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/app/vote/post/components/DrinkSearchModal.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/jurumarble/src/app/vote/post/components/DrinkSearchModal.tsx b/apps/jurumarble/src/app/vote/post/components/DrinkSearchModal.tsx index c96bb560..5ba104b2 100644 --- a/apps/jurumarble/src/app/vote/post/components/DrinkSearchModal.tsx +++ b/apps/jurumarble/src/app/vote/post/components/DrinkSearchModal.tsx @@ -57,7 +57,7 @@ function DrinkSearchModal({ onToggleDrinkSearchModal }: Props) { regionOption={regionOption} onChangeRegionOption={onChangeRegionOption} > - {regionOption && } + {/* {regionOption && } */} {selectedDrinkList.map((manufacturer) => ( @@ -69,7 +69,7 @@ function DrinkSearchModal({ onToggleDrinkSearchModal }: Props) { {regionOption && ( - {TEMP_LIST.map(({ drinkName, manufacturer }) => ( + {/* {TEMP_LIST.map(({ drinkName, manufacturer }) => ( - ))} + ))} */} 선택 완료