From 35d8a4fb2b0bc18205f25dc13ca787fdb19d10c3 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Fri, 23 Jan 2026 10:09:44 +0900 Subject: [PATCH 1/9] =?UTF-8?q?refactor:=20providers=ED=8F=B4=EB=8D=94=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20-=20HeroProvider,=20NaverMapProvider,=20Qu?= =?UTF-8?q?eryClientProvider=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/app/{ => _providers}/HeroProvider.tsx | 0 apps/web/app/{ => _providers}/NaverMapProvider.tsx | 0 .../app/{ => _providers}/QueryClientProvider.tsx | 0 apps/web/app/layout.tsx | 14 +++++++------- 4 files changed, 7 insertions(+), 7 deletions(-) rename apps/web/app/{ => _providers}/HeroProvider.tsx (100%) rename apps/web/app/{ => _providers}/NaverMapProvider.tsx (100%) rename apps/web/app/{ => _providers}/QueryClientProvider.tsx (100%) diff --git a/apps/web/app/HeroProvider.tsx b/apps/web/app/_providers/HeroProvider.tsx similarity index 100% rename from apps/web/app/HeroProvider.tsx rename to apps/web/app/_providers/HeroProvider.tsx diff --git a/apps/web/app/NaverMapProvider.tsx b/apps/web/app/_providers/NaverMapProvider.tsx similarity index 100% rename from apps/web/app/NaverMapProvider.tsx rename to apps/web/app/_providers/NaverMapProvider.tsx diff --git a/apps/web/app/QueryClientProvider.tsx b/apps/web/app/_providers/QueryClientProvider.tsx similarity index 100% rename from apps/web/app/QueryClientProvider.tsx rename to apps/web/app/_providers/QueryClientProvider.tsx diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index ab6ac51..d23f467 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -1,17 +1,17 @@ import '@repo/ui/styles.css' import './globals.css' +import { Suspense } from 'react' import Script from 'next/script' import type { Metadata } from 'next' -import { Suspense } from 'react' -import QueryProvider from './QueryClientProvider' import localFont from 'next/font/local' +import { GoogleAnalytics } from '@next/third-parties/google' +import QueryProvider from '@/_providers/QueryClientProvider' +import { NaverMapProvider } from '@/_providers/NaverMapProvider' +import { HeroProvider } from '@/_providers/HeroProvider' +import { CampusInitializer } from '@/CampusInitializer' +import { Column } from '@repo/ui/components/Layout' // import { initServerMSW } from '@/_mocks/initMSW' // import { MSWProvider } from '@/_mocks/MSWProvider' -import { Column } from '@repo/ui/components/Layout' -import { NaverMapProvider } from '@/NaverMapProvider' -import { HeroProvider } from '@/HeroProvider' -import { CampusInitializer } from '@/CampusInitializer' -import { GoogleAnalytics } from '@next/third-parties/google' const SITE_URL = new URL(process.env.NEXT_PUBLIC_CLIENT_URL || '') From 0b93a35a5dfb97bb027b66828adef17d6601ff8e Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Fri, 23 Jan 2026 10:19:16 +0900 Subject: [PATCH 2/9] =?UTF-8?q?refactor:=20PlaceMarker=EC=9D=98=20handlePr?= =?UTF-8?q?eviewPlace=20prop=EC=9D=B4=EB=A6=84=EC=9D=84=20onClick=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/app/map/MapComponent.tsx | 2 +- apps/web/app/map/_components/Marker/Marker.tsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/web/app/map/MapComponent.tsx b/apps/web/app/map/MapComponent.tsx index c1156fc..eede583 100644 --- a/apps/web/app/map/MapComponent.tsx +++ b/apps/web/app/map/MapComponent.tsx @@ -119,7 +119,7 @@ const MapComponent = () => { key={place.placeId} position={place.location} icon={place.categories[0]?.iconKey || 'logo'} - handlePreviewPlace={() => { + onClick={() => { handlePreviewPlace(place.placeId) }} /> diff --git a/apps/web/app/map/_components/Marker/Marker.tsx b/apps/web/app/map/_components/Marker/Marker.tsx index 727ed44..5e7a74f 100644 --- a/apps/web/app/map/_components/Marker/Marker.tsx +++ b/apps/web/app/map/_components/Marker/Marker.tsx @@ -36,11 +36,11 @@ export const UserMarker = ({ position }: { position: Coord }) => { export const PlaceMarker = ({ icon, position, - handlePreviewPlace = () => {}, + onClick = () => {}, }: { icon: IconType position: Coord - handlePreviewPlace?: VoidFunction + onClick?: VoidFunction }) => { const naverMaps = useNavermaps() const MarkerIcon = ReactDOMServer.renderToString( @@ -54,7 +54,7 @@ export const PlaceMarker = ({ { e.pointerEvent.stopPropagation() - handlePreviewPlace() + onClick() }} position={new naverMaps.LatLng(toLatLng(position))} icon={{ From cde7618bd1fe3799b1cd4cc5a2f431f0bf159785 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Fri, 23 Jan 2026 10:20:53 +0900 Subject: [PATCH 3/9] =?UTF-8?q?refactor:=20PreviewPlace=EB=A5=BC=20PlaceSu?= =?UTF-8?q?mmaryCard=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/app/map/MapComponent.tsx | 4 ++-- .../PlaceSummaryCard.tsx} | 2 +- apps/web/app/map/_components/PlaceSummaryCard/index.tsx | 1 + apps/web/app/map/_components/PreviewPlace/index.tsx | 1 - 4 files changed, 4 insertions(+), 4 deletions(-) rename apps/web/app/map/_components/{PreviewPlace/PreviewPlace.tsx => PlaceSummaryCard/PlaceSummaryCard.tsx} (96%) create mode 100644 apps/web/app/map/_components/PlaceSummaryCard/index.tsx delete mode 100644 apps/web/app/map/_components/PreviewPlace/index.tsx diff --git a/apps/web/app/map/MapComponent.tsx b/apps/web/app/map/MapComponent.tsx index eede583..218a5fe 100644 --- a/apps/web/app/map/MapComponent.tsx +++ b/apps/web/app/map/MapComponent.tsx @@ -17,7 +17,7 @@ import { PlaceList } from './_components/PlaceList' import { CampusButtonBox } from './_components/CampusButtom' import { UserMarker, PlaceMarker } from './_components/Marker' import { CurrentLocationButton } from './_components/CurrentLocationButton' -import { PreviewPlace } from './_components/PreviewPlace' +import { PlaceSummaryCard } from './_components/PlaceSummaryCard' import { RefreshButton } from './_components/RefreshButton' const MapComponent = () => { @@ -127,7 +127,7 @@ const MapComponent = () => { {previewPlace ? ( - + ) : ( )} diff --git a/apps/web/app/map/_components/PreviewPlace/PreviewPlace.tsx b/apps/web/app/map/_components/PlaceSummaryCard/PlaceSummaryCard.tsx similarity index 96% rename from apps/web/app/map/_components/PreviewPlace/PreviewPlace.tsx rename to apps/web/app/map/_components/PlaceSummaryCard/PlaceSummaryCard.tsx index d96dd08..c24aeec 100644 --- a/apps/web/app/map/_components/PreviewPlace/PreviewPlace.tsx +++ b/apps/web/app/map/_components/PlaceSummaryCard/PlaceSummaryCard.tsx @@ -8,7 +8,7 @@ import { Text } from '@repo/ui/components/Text' import { Icon } from '@repo/ui/components/Icon' import { Column, Flex } from '@repo/ui/components/Layout' -export const PreviewPlace = ({ place }: { place: PlaceByMap }) => { +export const PlaceSummaryCard = ({ place }: { place: PlaceByMap }) => { const { placeId, placeName, categories, address, photos } = place const mainCategoryIcon = categories[0]?.iconKey || 'logo' diff --git a/apps/web/app/map/_components/PlaceSummaryCard/index.tsx b/apps/web/app/map/_components/PlaceSummaryCard/index.tsx new file mode 100644 index 0000000..5bbe565 --- /dev/null +++ b/apps/web/app/map/_components/PlaceSummaryCard/index.tsx @@ -0,0 +1 @@ +export { PlaceSummaryCard } from './PlaceSummaryCard' diff --git a/apps/web/app/map/_components/PreviewPlace/index.tsx b/apps/web/app/map/_components/PreviewPlace/index.tsx deleted file mode 100644 index e733d72..0000000 --- a/apps/web/app/map/_components/PreviewPlace/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { PreviewPlace } from './PreviewPlace' From bdc6a6bb8526bae0e0d4f0dd6697c759881ffb24 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Fri, 23 Jan 2026 10:43:29 +0900 Subject: [PATCH 4/9] =?UTF-8?q?refactor:=20CurrentLocationButton=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=EC=84=9C=20previe?= =?UTF-8?q?wPlaceId=EB=A5=BC=20selectedPlaceId=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EB=B0=8F=20bottomOffset=20prop=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/web/app/map/MapComponent.tsx | 27 ++++++++----------- .../CurrentLocationButton.tsx | 11 ++++---- .../map/constants/CurrentLocationButton.ts | 7 +++++ 3 files changed, 24 insertions(+), 21 deletions(-) create mode 100644 apps/web/app/map/constants/CurrentLocationButton.ts diff --git a/apps/web/app/map/MapComponent.tsx b/apps/web/app/map/MapComponent.tsx index 218a5fe..5745692 100644 --- a/apps/web/app/map/MapComponent.tsx +++ b/apps/web/app/map/MapComponent.tsx @@ -7,6 +7,7 @@ import { Container, NaverMap } from 'react-naver-maps' import { CAMPUS_LOCATION } from '@/_constants/campus' import { useCampusStore } from '@/_store/campus' import { useLastMapCenterStore } from '@/_store/lastMapCenter' +import { BOTTOM_OFFSET } from './constants/CurrentLocationButton' import { usePlaceQueries } from '@/_apis/queries/place' import type { MapBounds } from '@/_apis/schemas/place' @@ -24,7 +25,7 @@ const MapComponent = () => { const [map, setMap] = useState(null) const [isCenteredOnUser, setIsCenteredOnUser] = useState(false) const [currentBounds, setCurrentBounds] = useState(null) - const [previewPlaceId, setPreviewPlaceId] = useState(null) + const [selectedPlaceId, setSelectedPlaceId] = useState(null) const [showUpdateButton, setShowUpdateButton] = useState(false) const { campus } = useCampusStore() @@ -33,8 +34,8 @@ const MapComponent = () => { const { data = [] } = useQuery(usePlaceQueries.byMap(currentBounds)) const defaultCenter = toLatLng(lastMapCenter || CAMPUS_LOCATION[campus]) - const previewPlace = previewPlaceId - ? data.find((place) => place.placeId === previewPlaceId)! + const selectedPlace = selectedPlaceId + ? data.find((place) => place.placeId === selectedPlaceId)! : null const refreshMapBounds = useCallback(() => { @@ -69,14 +70,7 @@ const MapComponent = () => { const onCenterChanged = () => { setIsCenteredOnUser(false) setShowUpdateButton(true) - } - - const handlePreviewPlace = (placeId: string) => { - setPreviewPlaceId(placeId) - } - - const resetPreviewPlace = () => { - setPreviewPlaceId(null) + setSelectedPlaceId(null) } useEffect(refreshMapBounds, [refreshMapBounds]) @@ -97,12 +91,13 @@ const MapComponent = () => { @@ -120,14 +115,14 @@ const MapComponent = () => { position={place.location} icon={place.categories[0]?.iconKey || 'logo'} onClick={() => { - handlePreviewPlace(place.placeId) + setSelectedPlaceId(place.placeId) }} /> ))} - {previewPlace ? ( - + {selectedPlace ? ( + ) : ( )} diff --git a/apps/web/app/map/_components/CurrentLocationButton/CurrentLocationButton.tsx b/apps/web/app/map/_components/CurrentLocationButton/CurrentLocationButton.tsx index 8d82e88..d8729b7 100644 --- a/apps/web/app/map/_components/CurrentLocationButton/CurrentLocationButton.tsx +++ b/apps/web/app/map/_components/CurrentLocationButton/CurrentLocationButton.tsx @@ -3,22 +3,23 @@ import { motion } from 'motion/react' import { Icon } from '@repo/ui/components/Icon' import { cn } from '@repo/ui/utils/cn' +import { BOTTOM_OFFSET } from '@/map/constants/CurrentLocationButton' type Props = { onClick: VoidFunction isCenteredOnUser: boolean - previewPlaceId: string | null + bottomOffset?: number } -const windowHeight = Math.floor(window.innerHeight * 0.2) + 10 + export const CurrentLocationButton = ({ onClick, isCenteredOnUser, - previewPlaceId, + bottomOffset, }: Props) => { return ( Date: Fri, 23 Jan 2026 13:07:02 +0900 Subject: [PATCH 5/9] =?UTF-8?q?feat:=20useDebounced=20=ED=9B=85=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=ED=95=98=EC=97=AC=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=8B=A4=ED=96=89=20=EC=A7=80=EC=97=B0=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/app/_hooks/useDebounced.ts | 53 +++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 apps/web/app/_hooks/useDebounced.ts diff --git a/apps/web/app/_hooks/useDebounced.ts b/apps/web/app/_hooks/useDebounced.ts new file mode 100644 index 0000000..188580d --- /dev/null +++ b/apps/web/app/_hooks/useDebounced.ts @@ -0,0 +1,53 @@ +import { useCallback, useEffect, useRef } from 'react' + +/** + * 함수 실행을 지정된 시간만큼 지연시키는 훅 (Debounce) + * + * @template T - 실행할 함수의 타입 + * @param func - 실행할 함수 (콜백) + * @param delay - 지연 시간 (ms) + * @returns 디바운스 처리된 실행 함수 + */ + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const useDebounced = any>( + func: T, + delay: number = 300, +) => { + const timeoutRef = useRef | null>(null) + + const funcRef = useRef(func) + + useEffect(() => { + funcRef.current = func + }, [func]) + + const trigger = useCallback( + (...args: Parameters) => { + if (timeoutRef.current) { + clearTimeout(timeoutRef.current) + } + + timeoutRef.current = setTimeout(async () => { + try { + // 최신 함수 호출 + await funcRef.current(...args) + } catch (error) { + console.error('Debounced function failed:', error) + } + }, delay) + }, + [delay], + ) + + // 언마운트 시 타이머 클리어 + useEffect(() => { + return () => { + if (timeoutRef.current) { + clearTimeout(timeoutRef.current) + } + } + }, []) + + return trigger +} From dbae9f48e60a4028b35ca5833d84704d97c7fe72 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Fri, 23 Jan 2026 13:08:44 +0900 Subject: [PATCH 6/9] =?UTF-8?q?feat:=20useDebounced=20=ED=9B=85=EC=9D=84?= =?UTF-8?q?=20onCenterChanged=20=ED=95=A8=EC=88=98=EC=97=90=20=ED=86=B5?= =?UTF-8?q?=ED=95=A9=ED=95=98=EC=97=AC=20=EC=8B=A4=ED=96=89=20=EC=A7=80?= =?UTF-8?q?=EC=97=B0=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/app/map/MapComponent.tsx | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/apps/web/app/map/MapComponent.tsx b/apps/web/app/map/MapComponent.tsx index 5745692..5c92b89 100644 --- a/apps/web/app/map/MapComponent.tsx +++ b/apps/web/app/map/MapComponent.tsx @@ -20,6 +20,7 @@ import { UserMarker, PlaceMarker } from './_components/Marker' import { CurrentLocationButton } from './_components/CurrentLocationButton' import { PlaceSummaryCard } from './_components/PlaceSummaryCard' import { RefreshButton } from './_components/RefreshButton' +import { useDebounced } from '@/_hooks/useDebounced' const MapComponent = () => { const [map, setMap] = useState(null) @@ -67,11 +68,11 @@ const MapComponent = () => { setIsCenteredOnUser(false) } - const onCenterChanged = () => { + const onCenterChanged = useDebounced(() => { setIsCenteredOnUser(false) setShowUpdateButton(true) setSelectedPlaceId(null) - } + }, 200) useEffect(refreshMapBounds, [refreshMapBounds]) useEffect(() => { @@ -96,17 +97,13 @@ const MapComponent = () => { } /> - + {userLocation && } {data.map((place) => ( From 95f45e08cd130af7bd697304e2cf0a03b0e98521 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Fri, 23 Jan 2026 13:12:21 +0900 Subject: [PATCH 7/9] =?UTF-8?q?refactor:=20HydrationBoundaryPage=20compone?= =?UTF-8?q?nt=EB=A5=BC=20=5Fcomponents=20=EB=94=94=EB=A0=89=ED=86=A0?= =?UTF-8?q?=EB=A6=AC=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/app/(home)/page.tsx | 2 +- apps/web/app/{ => _components}/HydrationBoundaryPage.tsx | 0 apps/web/app/categories/[id]/page.tsx | 2 +- apps/web/app/events/food-slot/page.tsx | 2 +- apps/web/app/events/lucky-draw/page.tsx | 2 +- apps/web/app/likes/page.tsx | 2 +- apps/web/app/places/[id]/page.tsx | 2 +- apps/web/app/profile/page.tsx | 2 +- apps/web/app/requests/[id]/page.tsx | 2 +- apps/web/app/requests/page.tsx | 2 +- 10 files changed, 9 insertions(+), 9 deletions(-) rename apps/web/app/{ => _components}/HydrationBoundaryPage.tsx (100%) diff --git a/apps/web/app/(home)/page.tsx b/apps/web/app/(home)/page.tsx index 575dd11..626c4a4 100644 --- a/apps/web/app/(home)/page.tsx +++ b/apps/web/app/(home)/page.tsx @@ -7,7 +7,7 @@ import { Flex, VerticalScrollArea } from '@repo/ui/components/Layout' import { Icon } from '@repo/ui/components/Icon' import { Text } from '@repo/ui/components/Text' import { Divider } from '@repo/ui/components/Divider' -import { HydrationBoundaryPage } from '@/HydrationBoundaryPage' +import { HydrationBoundaryPage } from '@/_components/HydrationBoundaryPage' import { Banner } from '@repo/ui/components/Banner' import { Categories } from '@/_components/Categories' import { BottomNavigation } from '@/_components/BottomNavigation' diff --git a/apps/web/app/HydrationBoundaryPage.tsx b/apps/web/app/_components/HydrationBoundaryPage.tsx similarity index 100% rename from apps/web/app/HydrationBoundaryPage.tsx rename to apps/web/app/_components/HydrationBoundaryPage.tsx diff --git a/apps/web/app/categories/[id]/page.tsx b/apps/web/app/categories/[id]/page.tsx index ac8be29..32444e2 100644 --- a/apps/web/app/categories/[id]/page.tsx +++ b/apps/web/app/categories/[id]/page.tsx @@ -1,5 +1,5 @@ import type { Metadata } from 'next' -import { HydrationBoundaryPage } from '@/HydrationBoundaryPage' +import { HydrationBoundaryPage } from '@/_components/HydrationBoundaryPage' import { useCategoryQueries } from '@/_apis/queries/category' import { CategoryDetailPage } from '@/categories/[id]/CategoryDetailPage' import { getCategories } from '@/_apis/services/category' diff --git a/apps/web/app/events/food-slot/page.tsx b/apps/web/app/events/food-slot/page.tsx index 9cb3e4c..3ff7577 100644 --- a/apps/web/app/events/food-slot/page.tsx +++ b/apps/web/app/events/food-slot/page.tsx @@ -1,5 +1,5 @@ import type { Metadata } from 'next' -import { HydrationBoundaryPage } from '@/HydrationBoundaryPage' +import { HydrationBoundaryPage } from '@/_components/HydrationBoundaryPage' import { useCategoryQueries } from '@/_apis/queries/category' import FoodSlotMachine from './FoodSlotMachine' import { Header } from '@repo/ui/components/Header' diff --git a/apps/web/app/events/lucky-draw/page.tsx b/apps/web/app/events/lucky-draw/page.tsx index f0b218e..8251941 100644 --- a/apps/web/app/events/lucky-draw/page.tsx +++ b/apps/web/app/events/lucky-draw/page.tsx @@ -4,7 +4,7 @@ import { Flex } from '@repo/ui/components/Layout' import { Icon } from '@repo/ui/components/Icon' import { Text } from '@repo/ui/components/Text' import { LuckyDraw } from './LuckyDraw' -import { HydrationBoundaryPage } from '@/HydrationBoundaryPage' +import { HydrationBoundaryPage } from '@/_components/HydrationBoundaryPage' import { useEventQueries } from '@/_apis/queries/event' import { InfoPopover } from './_components/InfoPopover' diff --git a/apps/web/app/likes/page.tsx b/apps/web/app/likes/page.tsx index 0b6b07f..a97697e 100644 --- a/apps/web/app/likes/page.tsx +++ b/apps/web/app/likes/page.tsx @@ -2,7 +2,7 @@ import type { Metadata } from 'next' import { usePlaceQueries } from '@/_apis/queries/place' import { OnlyLeftHeader } from '@repo/ui/components/Header' import { VerticalScrollArea } from '@repo/ui/components/Layout' -import { HydrationBoundaryPage } from '@/HydrationBoundaryPage' +import { HydrationBoundaryPage } from '@/_components/HydrationBoundaryPage' import { LikePlacesList } from './_components/LikePlacesList' import { BottomNavigation } from '@/_components/BottomNavigation' diff --git a/apps/web/app/places/[id]/page.tsx b/apps/web/app/places/[id]/page.tsx index 4a9dfca..5d52209 100644 --- a/apps/web/app/places/[id]/page.tsx +++ b/apps/web/app/places/[id]/page.tsx @@ -1,6 +1,6 @@ import type { Metadata } from 'next' import { usePlaceQueries } from '@/_apis/queries/place' -import { HydrationBoundaryPage } from '@/HydrationBoundaryPage' +import { HydrationBoundaryPage } from '@/_components/HydrationBoundaryPage' import { PlaceDetailPage } from './PlaceDetailPage' import { getPlaceDetail } from '@/_apis/services/place' diff --git a/apps/web/app/profile/page.tsx b/apps/web/app/profile/page.tsx index b9b0b42..b83e27c 100644 --- a/apps/web/app/profile/page.tsx +++ b/apps/web/app/profile/page.tsx @@ -1,6 +1,6 @@ import { CLIENT_PATH } from '@/_constants/path' import { useUserQueries } from '@/_apis/queries/user' -import { HydrationBoundaryPage } from '@/HydrationBoundaryPage' +import { HydrationBoundaryPage } from '@/_components/HydrationBoundaryPage' import { BottomNavigation } from '@/_components/BottomNavigation' import { OnlyLeftHeader } from '@repo/ui/components/Header' import { Column } from '@repo/ui/components/Layout' diff --git a/apps/web/app/requests/[id]/page.tsx b/apps/web/app/requests/[id]/page.tsx index 7f21b84..3716a50 100644 --- a/apps/web/app/requests/[id]/page.tsx +++ b/apps/web/app/requests/[id]/page.tsx @@ -1,5 +1,5 @@ import { RequestDetailPage } from './RequestDetailPage' -import { HydrationBoundaryPage } from '@/HydrationBoundaryPage' +import { HydrationBoundaryPage } from '@/_components/HydrationBoundaryPage' import { useRequestQueries } from '@/_apis/queries/request' export const dynamic = 'force-dynamic' diff --git a/apps/web/app/requests/page.tsx b/apps/web/app/requests/page.tsx index 2a3a3ac..bac3f2e 100644 --- a/apps/web/app/requests/page.tsx +++ b/apps/web/app/requests/page.tsx @@ -5,7 +5,7 @@ import { Icon } from '@repo/ui/components/Icon' import { Text } from '@repo/ui/components/Text' import { useRequestQueries } from '@/_apis/queries/request' -import { HydrationBoundaryPage } from '@/HydrationBoundaryPage' +import { HydrationBoundaryPage } from '@/_components/HydrationBoundaryPage' import { RequestPlacesList } from './_components/RequestPlacesList' export const dynamic = 'force-dynamic' From 8889309f84548521bcd8c68e641234357a2d4b52 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Fri, 23 Jan 2026 13:12:34 +0900 Subject: [PATCH 8/9] =?UTF-8?q?refactor:=20CampusInitializer=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=EB=A5=BC=20=5Fcomponents=20?= =?UTF-8?q?=EB=94=94=EB=A0=89=ED=86=A0=EB=A6=AC=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/app/{ => _components}/CampusInitializer.tsx | 0 apps/web/app/layout.tsx | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename apps/web/app/{ => _components}/CampusInitializer.tsx (100%) diff --git a/apps/web/app/CampusInitializer.tsx b/apps/web/app/_components/CampusInitializer.tsx similarity index 100% rename from apps/web/app/CampusInitializer.tsx rename to apps/web/app/_components/CampusInitializer.tsx diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index d23f467..1e4897c 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -8,7 +8,7 @@ import { GoogleAnalytics } from '@next/third-parties/google' import QueryProvider from '@/_providers/QueryClientProvider' import { NaverMapProvider } from '@/_providers/NaverMapProvider' import { HeroProvider } from '@/_providers/HeroProvider' -import { CampusInitializer } from '@/CampusInitializer' +import { CampusInitializer } from '@/_components/CampusInitializer' import { Column } from '@repo/ui/components/Layout' // import { initServerMSW } from '@/_mocks/initMSW' // import { MSWProvider } from '@/_mocks/MSWProvider' From 322c1d9dc58f2c48dc472b396d7cd125cac178b3 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Fri, 23 Jan 2026 13:29:02 +0900 Subject: [PATCH 9/9] =?UTF-8?q?refactor:=20Banner=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=9D=B4=EB=A6=84=EC=9D=84=20Carousel?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20-=20contents=20prop=EC=9D=84?= =?UTF-8?q?=20children=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/requests/[id]/RequestDetailPage.tsx | 10 +++--- apps/web/app/(home)/page.tsx | 12 +++---- apps/web/app/places/[id]/PlaceDetailPage.tsx | 10 +++--- .../Step/PlacePreview/PlacePreview.tsx | 10 +++--- .../app/requests/[id]/RequestDetailPage.tsx | 10 +++--- packages/ui/src/components/Banner/index.tsx | 1 - .../Banner.tsx => Carousel/Carousel.tsx} | 31 +++++++++---------- packages/ui/src/components/Carousel/index.tsx | 1 + 8 files changed, 36 insertions(+), 49 deletions(-) delete mode 100644 packages/ui/src/components/Banner/index.tsx rename packages/ui/src/components/{Banner/Banner.tsx => Carousel/Carousel.tsx} (87%) create mode 100644 packages/ui/src/components/Carousel/index.tsx diff --git a/apps/admin/src/app/requests/[id]/RequestDetailPage.tsx b/apps/admin/src/app/requests/[id]/RequestDetailPage.tsx index 2a704e0..3d567d4 100644 --- a/apps/admin/src/app/requests/[id]/RequestDetailPage.tsx +++ b/apps/admin/src/app/requests/[id]/RequestDetailPage.tsx @@ -8,7 +8,7 @@ import { Header } from '@repo/ui/components/Header' import { Icon } from '@repo/ui/components/Icon' import { Text } from '@repo/ui/components/Text' import { Column, VerticalScrollArea } from '@repo/ui/components/Layout' -import { Banner } from '@repo/ui/components/Banner' +import { Carousel } from '@repo/ui/components/Carousel' import type { RequestDetail } from './_api/types' import { CLIENT_PATH } from '@/consts/path' @@ -56,8 +56,8 @@ export const RequestDetailPage = ({ data }: Props) => { /> {photos.length > 0 && ( - ( + + {photos.map((photo) => ( { className={'max-h-[180px] object-contain'} /> ))} - minHeight={180} - showIndicator={true} - /> + )}
diff --git a/apps/web/app/(home)/page.tsx b/apps/web/app/(home)/page.tsx index 626c4a4..b85b669 100644 --- a/apps/web/app/(home)/page.tsx +++ b/apps/web/app/(home)/page.tsx @@ -8,7 +8,7 @@ import { Icon } from '@repo/ui/components/Icon' import { Text } from '@repo/ui/components/Text' import { Divider } from '@repo/ui/components/Divider' import { HydrationBoundaryPage } from '@/_components/HydrationBoundaryPage' -import { Banner } from '@repo/ui/components/Banner' +import { Carousel } from '@repo/ui/components/Carousel' import { Categories } from '@/_components/Categories' import { BottomNavigation } from '@/_components/BottomNavigation' import { RankingSection } from './_components/RankingSection' @@ -47,12 +47,10 @@ export default function Page() { > - , - , - ]} - /> + + + + { right={} /> - ( + + {photos.map((photo, index) => ( { priority={index === 0} /> ))} - minHeight={180} - showIndicator={true} - /> +
diff --git a/apps/web/app/places/new/_components/Step/PlacePreview/PlacePreview.tsx b/apps/web/app/places/new/_components/Step/PlacePreview/PlacePreview.tsx index 7641519..428d8ba 100644 --- a/apps/web/app/places/new/_components/Step/PlacePreview/PlacePreview.tsx +++ b/apps/web/app/places/new/_components/Step/PlacePreview/PlacePreview.tsx @@ -3,7 +3,7 @@ import { useSuspenseQuery } from '@tanstack/react-query' import type { UseFormGetValues, UseFormSetValue } from 'react-hook-form' import type { NewPlaceRequest } from '@/_apis/schemas/place' import { usePlaceQueries } from '@/_apis/queries/place' -import { Banner } from '@repo/ui/components/Banner' +import { Carousel } from '@repo/ui/components/Carousel' import { Location, Menus } from '@/places/[id]/_components' import { Text } from '@repo/ui/components/Text' import { Button } from '@repo/ui/components/Button' @@ -51,8 +51,8 @@ export const PlacePreview = ({ getValues, setValue, nextStep }: Props) => { - ( + + {photos.map((photo) => ( { className={'max-h-[180px] object-contain'} /> ))} - showIndicator={true} - minHeight={180} - /> +
diff --git a/apps/web/app/requests/[id]/RequestDetailPage.tsx b/apps/web/app/requests/[id]/RequestDetailPage.tsx index 9023b26..8edcf67 100644 --- a/apps/web/app/requests/[id]/RequestDetailPage.tsx +++ b/apps/web/app/requests/[id]/RequestDetailPage.tsx @@ -7,7 +7,7 @@ import { useRequestQueries } from '@/_apis/queries/request' import { Header } from '@repo/ui/components/Header' import { Text } from '@repo/ui/components/Text' import { Column, VerticalScrollArea } from '@repo/ui/components/Layout' -import { Banner } from '@repo/ui/components/Banner' +import { Carousel } from '@repo/ui/components/Carousel' import { HeaderBackButton } from '@/_components/HeaderBackButton' import { Description, Location, Menus, Tags } from '@/places/[id]/_components' import { StatusChip } from '@/requests/_components/StatusChip' @@ -42,8 +42,8 @@ export const RequestDetailPage = ({ id }: { id: string }) => { {rejectedReason && registerStatus === 'REJECTED' && ( )} - ( + + {photos.map((photo) => ( { className={'max-h-[180px] object-contain'} /> ))} - minHeight={180} - showIndicator={true} - /> +
diff --git a/packages/ui/src/components/Banner/index.tsx b/packages/ui/src/components/Banner/index.tsx deleted file mode 100644 index 1a83a85..0000000 --- a/packages/ui/src/components/Banner/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { Banner } from './Banner' diff --git a/packages/ui/src/components/Banner/Banner.tsx b/packages/ui/src/components/Carousel/Carousel.tsx similarity index 87% rename from packages/ui/src/components/Banner/Banner.tsx rename to packages/ui/src/components/Carousel/Carousel.tsx index 842feec..2ed0c06 100644 --- a/packages/ui/src/components/Banner/Banner.tsx +++ b/packages/ui/src/components/Carousel/Carousel.tsx @@ -1,49 +1,46 @@ 'use client' -import { useState } from 'react' +import { useState, type ReactNode } from 'react' import 'keen-slider/keen-slider.min.css' import { useKeenSlider } from 'keen-slider/react' import { cn } from '@repo/ui/utils/cn' type Props = { - contents: React.ReactNode[] minHeight?: number showIndicator?: boolean + children: ReactNode[] } /** - * Banner 컴포넌트 + * Carousel 컴포넌트 * * - 여러 콘텐츠를 순차적으로 보여주는 슬라이더 배너입니다. * - `keen-slider`를 기반으로 자동 재생(loop) 기능을 제공합니다. * - 마우스를 올리면 자동 재생이 일시 정지되고, 마우스를 치우면 다시 재생됩니다. * - * @param contents 렌더링할 React 노드 배열 (각각의 배너 콘텐츠) + * @param children 렌더링할 React 노드 배열 (각각의 배너 콘텐츠) * @param minHeight 배너의 최소 높이(px). 기본값은 150입니다. * @param showIndicator 인디케이터 노출 유무. 기본값은 false 입니다. * * @example * ```tsx - * 배너 1, - *
배너 2
, - *
배너 3
, - * ]} - * minHeight={200} - * /> + * + *
배너 1
+ *
배너 2
+ *
배너 3
+ *
* ``` */ -export const Banner = ({ - contents, +export const Carousel = ({ minHeight = 150, showIndicator = false, + children, }: Props) => { const [currentSlide, setCurrentSlide] = useState(0) const [loaded, setLoaded] = useState(false) const [sliderRef, instanceRef] = useKeenSlider( { - loop: contents.length > 1, + loop: children.length > 1, initial: 0, slideChanged(slider) { setCurrentSlide(slider.track.details.rel) @@ -90,7 +87,7 @@ export const Banner = ({ ], ) - if (contents.length === 0) { + if (children.length === 0) { return null } @@ -100,7 +97,7 @@ export const Banner = ({ className={'keen-slider ui:relative'} style={{ minHeight }} > - {contents.map((content, index) => ( + {children.map((content, index) => (