From 8d9b29b2bbf36e5ac7080d0105f6e3fef2afc211 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Mon, 1 Dec 2025 14:07:23 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20RequestDetailSchema=20=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EA=B1=B0=EB=B6=80=20=EC=82=AC=EC=9C=A0=EB=A5=BC=20?= =?UTF-8?q?nullable=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/app/_apis/schemas/request.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/app/_apis/schemas/request.ts b/apps/web/app/_apis/schemas/request.ts index c96c340..f7dcec8 100644 --- a/apps/web/app/_apis/schemas/request.ts +++ b/apps/web/app/_apis/schemas/request.ts @@ -16,7 +16,7 @@ export const RequestDetailSchema = PlaceDetailSchema.omit({ isLiked: true, }).extend({ registerStatus, - rejectedReason: z.optional(z.string()), + rejectedReason: z.nullable(z.string()), }) export type Request = z.infer From 9174a2c6c19e41e04b32164e208cfdfca1a5c85f Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Mon, 1 Dec 2025 14:08:06 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20next.config.ts=EC=97=90=20images.re?= =?UTF-8?q?motePatterns=20=EC=9A=94=EC=86=8C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/next.config.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/web/next.config.ts b/apps/web/next.config.ts index e27f557..dcc071a 100644 --- a/apps/web/next.config.ts +++ b/apps/web/next.config.ts @@ -25,6 +25,11 @@ const nextConfig: NextConfig = { hostname: 't1.daumcdn.net', pathname: '/**', }, + { + protocol: 'https', + hostname: 't1.kakaocdn.net', + pathname: '/**', + }, { protocol: 'http', hostname: 't1.kakaocdn.net', From e3251a353f61643fe2859ae4c9fae96346521df9 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Mon, 1 Dec 2025 14:08:30 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20HydrationBoundaryPage=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/app/requests/page.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/apps/web/app/requests/page.tsx b/apps/web/app/requests/page.tsx index 7c7a67a..2a3a3ac 100644 --- a/apps/web/app/requests/page.tsx +++ b/apps/web/app/requests/page.tsx @@ -12,11 +12,7 @@ export const dynamic = 'force-dynamic' const Page = async () => { return ( - { - await queryClient.prefetchQuery(useRequestQueries.list()) - }} - > + <>
} center={ @@ -26,8 +22,14 @@ const Page = async () => { } /> - - + { + await queryClient.prefetchQuery(useRequestQueries.list()) + }} + > + + + ) } From e0fc71f79fb2f65d61c5b24fac5671227473078e Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Mon, 1 Dec 2025 14:09:08 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20PlaceListItem=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=EC=97=90=EC=84=9C=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=EB=A7=81=ED=81=AC=EC=97=90=20placeId=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/requests/_components/PlaceListItem/PlaceListItem.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/web/app/requests/_components/PlaceListItem/PlaceListItem.tsx b/apps/web/app/requests/_components/PlaceListItem/PlaceListItem.tsx index 8714d15..19da9de 100644 --- a/apps/web/app/requests/_components/PlaceListItem/PlaceListItem.tsx +++ b/apps/web/app/requests/_components/PlaceListItem/PlaceListItem.tsx @@ -8,7 +8,7 @@ import { StatusChip } from '../StatusChip' import type { Request } from '@/_apis/schemas/request' export const PlaceListItem = ({ - // placeId, + placeId, placeName, categories, requestDate, @@ -21,7 +21,7 @@ export const PlaceListItem = ({ From 118265d5984b82a51d6904e3b08146e4f9a56732 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Mon, 1 Dec 2025 14:15:33 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feat:=20=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=EC=9D=98=20=EB=B9=88=20=EC=83=81=ED=83=9C=EC=9D=98=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=EC=A1=B0=EA=B1=B4=EB=B6=80=20=EB=A0=8C=EB=8D=94?= =?UTF-8?q?=EB=A7=81=EC=9D=84=20=EC=9C=84=ED=95=9C=20EmptyFallback=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EmptyFallback/EmptyFallback.tsx | 55 +++++++++++++++++++ .../app/_components/EmptyFallback/index.tsx | 1 + 2 files changed, 56 insertions(+) create mode 100644 apps/web/app/_components/EmptyFallback/EmptyFallback.tsx create mode 100644 apps/web/app/_components/EmptyFallback/index.tsx diff --git a/apps/web/app/_components/EmptyFallback/EmptyFallback.tsx b/apps/web/app/_components/EmptyFallback/EmptyFallback.tsx new file mode 100644 index 0000000..35ab7f6 --- /dev/null +++ b/apps/web/app/_components/EmptyFallback/EmptyFallback.tsx @@ -0,0 +1,55 @@ +import { Column } from '@repo/ui/components/Layout' +import { Text } from '@repo/ui/components/Text' +import { ReactNode } from 'react' + +type Props = { + /** 데이터가 비어있는지 여부 (true면 Fallback, false면 children 렌더링) */ + isEmpty: boolean + /** 데이터가 비어있을 때 보여줄 제목 (예: "검색 결과가 없습니다") */ + fallbackTitle?: string + /** 데이터가 비어있을 때 보여줄 상세 설명 */ + fallbackDescription?: string + /** 데이터가 존재할 때 렌더링할 실제 콘텐츠 */ + children: ReactNode +} + +/** + * 데이터 유무(`isEmpty`)에 따라 Fallback UI 또는 실제 콘텐츠를 조건부 렌더링하는 래퍼 컴포넌트입니다. + * + * @example + * ```tsx + * + * + * + * ``` + */ +export const EmptyFallback = ({ + isEmpty, + fallbackTitle, + fallbackDescription, + children, +}: Props) => { + if (!isEmpty) return <>{children} + + return ( + + {fallbackTitle && ( + + {fallbackTitle} + + )} + {fallbackDescription && ( + + {fallbackDescription} + + )} + + ) +} diff --git a/apps/web/app/_components/EmptyFallback/index.tsx b/apps/web/app/_components/EmptyFallback/index.tsx new file mode 100644 index 0000000..69243a5 --- /dev/null +++ b/apps/web/app/_components/EmptyFallback/index.tsx @@ -0,0 +1 @@ +export { EmptyFallback } from './EmptyFallback' From 0c08f48720e8224fd9e6e214c3a0ad82497aab14 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Mon, 1 Dec 2025 14:16:05 +0900 Subject: [PATCH 6/7] =?UTF-8?q?feat:=20RequestPlacesList=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=20EmptyFallback=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=ED=95=98=EC=97=AC=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EA=B0=80=20=EC=97=86=EC=9D=84=20=EB=95=8C=20=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=EB=B6=80=20=EB=A0=8C=EB=8D=94=EB=A7=81=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 --- .../RequestPlacesList/RequestPlacesList.tsx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/apps/web/app/requests/_components/RequestPlacesList/RequestPlacesList.tsx b/apps/web/app/requests/_components/RequestPlacesList/RequestPlacesList.tsx index 1b8d82d..0b44cfd 100644 --- a/apps/web/app/requests/_components/RequestPlacesList/RequestPlacesList.tsx +++ b/apps/web/app/requests/_components/RequestPlacesList/RequestPlacesList.tsx @@ -2,15 +2,22 @@ import { useSuspenseQuery } from '@tanstack/react-query' import { useRequestQueries } from '@/_apis/queries/request' import { PlaceListItem } from '../PlaceListItem' +import { EmptyFallback } from '@/_components/EmptyFallback' export const RequestPlacesList = () => { const { data } = useSuspenseQuery(useRequestQueries.list()) return ( -
    - {data.map((place) => ( - - ))} -
+ +
    + {data.map((place) => ( + + ))} +
+
) } From aa3b67437bcc20f1f5775608780a78bc40fcf375 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Mon, 1 Dec 2025 14:16:25 +0900 Subject: [PATCH 7/7] =?UTF-8?q?feat:=20LikePlacesList=20=EB=B0=8F=20PlaceL?= =?UTF-8?q?ist=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=20EmptyFall?= =?UTF-8?q?back=20=EC=B6=94=EA=B0=80=ED=95=98=EC=97=AC=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=EA=B0=80=20=EC=97=86=EC=9D=84=20=EB=95=8C=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=EB=B6=80=20=EB=A0=8C=EB=8D=94=EB=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LikePlacesList/LikePlacesList.tsx | 42 +++++++------------ .../map/_components/PlaceList/PlaceList.tsx | 17 +++----- 2 files changed, 22 insertions(+), 37 deletions(-) diff --git a/apps/web/app/likes/_components/LikePlacesList/LikePlacesList.tsx b/apps/web/app/likes/_components/LikePlacesList/LikePlacesList.tsx index 1f1b644..1b0baaf 100644 --- a/apps/web/app/likes/_components/LikePlacesList/LikePlacesList.tsx +++ b/apps/web/app/likes/_components/LikePlacesList/LikePlacesList.tsx @@ -3,36 +3,26 @@ import { useSuspenseQuery } from '@tanstack/react-query' import { usePlaceQueries } from '@/_apis/queries/place' import { PlaceListItem } from '@/_components/PlaceListItem' -import { Text } from '@repo/ui/components/Text' -import { Column } from '@repo/ui/components/Layout' +import { EmptyFallback } from '@/_components/EmptyFallback' export const LikePlacesList = () => { const { data: places = [] } = useSuspenseQuery(usePlaceQueries.byLike()) - if (places.length === 0) { - return ( - - - {/*아직 찜한 맛집이 없어요*/} - 나만의 맛집 리스트를 만들어보세요! - - - {/*하트를 눌러 나만의 맛집을 저장해보세요!*/} - 자주 가는 식당을 찜해두면 편하게 볼 수 있어요. - - - ) - } - return ( -
    - {places.map((place, index) => ( - - ))} -
+ +
    + {places.map((place, index) => ( + + ))} +
+
) } diff --git a/apps/web/app/map/_components/PlaceList/PlaceList.tsx b/apps/web/app/map/_components/PlaceList/PlaceList.tsx index e53b7d9..b619c4b 100644 --- a/apps/web/app/map/_components/PlaceList/PlaceList.tsx +++ b/apps/web/app/map/_components/PlaceList/PlaceList.tsx @@ -5,7 +5,7 @@ import { useRef } from 'react' import { BottomSheet, type BottomSheetRef } from 'react-spring-bottom-sheet' import type { PlaceByMap } from '@/_apis/schemas/place' import { PlaceListItem } from '@/_components/PlaceListItem' -import { Text } from '@repo/ui/components/Text' +import { EmptyFallback } from '@/_components/EmptyFallback' export const PlaceList = ({ places }: { places: PlaceByMap[] }) => { const sheetRef = useRef(null) @@ -23,21 +23,16 @@ export const PlaceList = ({ places }: { places: PlaceByMap[] }) => { ]} expandOnContentDrag > - {places.length > 0 ? ( +
    {places.map((place) => ( ))}
- ) : ( - - 주위 검색된 맛집이 없습니다 - - )} +
) }