From 2d8dd0a219db1e9714b22ca9db83a124e95aa78e Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Wed, 18 Feb 2026 23:54:15 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20=EB=A7=9B=EC=A7=91=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90=20=EB=84=A4?= =?UTF-8?q?=EC=9D=B4=EB=B2=84=20=EC=A7=80=EB=8F=84=20=EB=94=A5=EB=A7=81?= =?UTF-8?q?=ED=81=AC=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 네이버 지도 앱/웹으로 이동하는 openNaverMap 유틸 함수 구현 - Location 컴포넌트에 네이버 지도로 이동 버튼 추가 (지도 우측 상단) - 모바일: 네이버 지도 앱 실행 (미설치 시 웹으로 폴백) - 데스크톱: 네이버 지도 웹 페이지를 새 탭으로 열기 - 장소명과 좌표를 파라미터로 전달하여 정확한 위치 표시 --- apps/web/app/_utils/openNaverMap/index.ts | 1 + .../app/_utils/openNaverMap/openNaverMap.ts | 37 +++++++++++ apps/web/app/places/[id]/PlaceDetailPage.tsx | 2 +- .../[id]/_components/Location/Location.tsx | 58 ++++++++++++++---- apps/web/public/images/naver-map-logo.webp | Bin 0 -> 5576 bytes 5 files changed, 86 insertions(+), 12 deletions(-) create mode 100644 apps/web/app/_utils/openNaverMap/index.ts create mode 100644 apps/web/app/_utils/openNaverMap/openNaverMap.ts create mode 100644 apps/web/public/images/naver-map-logo.webp diff --git a/apps/web/app/_utils/openNaverMap/index.ts b/apps/web/app/_utils/openNaverMap/index.ts new file mode 100644 index 00000000..1c7e4e73 --- /dev/null +++ b/apps/web/app/_utils/openNaverMap/index.ts @@ -0,0 +1 @@ +export { openNaverMap } from './openNaverMap' diff --git a/apps/web/app/_utils/openNaverMap/openNaverMap.ts b/apps/web/app/_utils/openNaverMap/openNaverMap.ts new file mode 100644 index 00000000..a9be8e8b --- /dev/null +++ b/apps/web/app/_utils/openNaverMap/openNaverMap.ts @@ -0,0 +1,37 @@ +interface OpenNaverMapParams { + latitude: number + longitude: number + placeName?: string +} + +/** + * 네이버 지도 앱으로 특정 위치를 여는 딥링크 함수 + * - 모바일: 네이버 지도 앱이 설치되어 있으면 앱 실행, 없으면 앱스토어로 이동 + * - 데스크톱: 네이버 지도 웹 페이지로 이동 + */ +export const openNaverMap = ({ + latitude, + longitude, + placeName, +}: OpenNaverMapParams): void => { + // 네이버 지도 URL 스킴 (앱) + const appScheme = `nmap://place?lat=${latitude}&lng=${longitude}&name=${encodeURIComponent(placeName || '위치')}&appname=com.matzip` + + // 네이버 지도 웹 URL (폴백) + const webUrl = `https://map.naver.com/p/search/${encodeURIComponent(placeName || '')}?c=${longitude},${latitude},18,0,0,0,dh` + + const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) + + if (isMobile) { + // 모바일: 딥링크 시도 + window.location.href = appScheme + + // 앱이 설치되지 않은 경우를 대비한 타임아웃 (2.5초 후 웹으로 폴백) + setTimeout(() => { + window.location.href = webUrl + }, 2500) + } else { + // 데스크톱: 웹 페이지로 바로 이동 + window.open(webUrl, '_blank') + } +} diff --git a/apps/web/app/places/[id]/PlaceDetailPage.tsx b/apps/web/app/places/[id]/PlaceDetailPage.tsx index 5e1e34fc..a8c043a9 100644 --- a/apps/web/app/places/[id]/PlaceDetailPage.tsx +++ b/apps/web/app/places/[id]/PlaceDetailPage.tsx @@ -62,7 +62,7 @@ export const PlaceDetailPage = ({ id }: { id: string }) => {
- +
diff --git a/apps/web/app/places/[id]/_components/Location/Location.tsx b/apps/web/app/places/[id]/_components/Location/Location.tsx index 503d83ed..5a2300d4 100644 --- a/apps/web/app/places/[id]/_components/Location/Location.tsx +++ b/apps/web/app/places/[id]/_components/Location/Location.tsx @@ -2,20 +2,56 @@ import { useState } from 'react' import { Container, NaverMap } from 'react-naver-maps' import { type Coord, toLatLng } from '@/map/_utils/toLatLng' import { PlaceMarker } from '@/map/_components/Marker' +import { Column } from '@repo/ui/components/Layout' +import { openNaverMap } from '@/_utils/openNaverMap' +import Image from 'next/image' -export const Location = ({ location }: { location: Coord }) => { +interface LocationProps { + location: Coord + placeName: string +} + +export const Location = ({ location, placeName }: LocationProps) => { const [, setMap] = useState(null) + const handleOpenNaverMap = () => { + openNaverMap({ + latitude: location.latitude, + longitude: location.longitude, + placeName, + }) + } + return ( - - - - - + + + + + + + + ) } + +const OpenNaverMapButton = ({ onClick }: { onClick: VoidFunction }) => ( + +) diff --git a/apps/web/public/images/naver-map-logo.webp b/apps/web/public/images/naver-map-logo.webp new file mode 100644 index 0000000000000000000000000000000000000000..b2ea97268b59095878eab6fa0a673fc48d8c3b89 GIT binary patch literal 5576 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 Sx Date: Thu, 19 Feb 2026 00:13:56 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20=EB=A7=9B=EC=A7=91=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90=20=EC=B9=B4?= =?UTF-8?q?=EC=B9=B4=EC=98=A4=ED=83=9D=EC=8B=9C=20=EB=94=A5=EB=A7=81?= =?UTF-8?q?=ED=81=AC=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 카카오택시 앱으로 이동하는 openKakaoTaxi 유틸 함수 구현 - Location 컴포넌트에 카카오택시 호출 버튼 추가 (지도 우측 상단) - 모바일: 카카오택시 앱 실행 (미설치 시 앱스토어로 이동) - 데스크톱: 모바일 전용 안내 토스트 메시지 표시 - MapButton 컴포넌트로 리팩토링하여 네이버 지도와 카카오택시 버튼 통합 - 버튼 세로 배치 및 hover 효과 추가 (scale-105) --- apps/web/app/_utils/openKakaoTaxi/index.ts | 1 + .../app/_utils/openKakaoTaxi/openKakaoTaxi.ts | 42 +++++++++++++++ .../[id]/_components/Location/Location.tsx | 50 ++++++++++++++---- apps/web/public/images/kakao-taxi-logo.png | Bin 0 -> 2476 bytes 4 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 apps/web/app/_utils/openKakaoTaxi/index.ts create mode 100644 apps/web/app/_utils/openKakaoTaxi/openKakaoTaxi.ts create mode 100644 apps/web/public/images/kakao-taxi-logo.png diff --git a/apps/web/app/_utils/openKakaoTaxi/index.ts b/apps/web/app/_utils/openKakaoTaxi/index.ts new file mode 100644 index 00000000..6c644141 --- /dev/null +++ b/apps/web/app/_utils/openKakaoTaxi/index.ts @@ -0,0 +1 @@ +export { openKakaoTaxi } from './openKakaoTaxi' diff --git a/apps/web/app/_utils/openKakaoTaxi/openKakaoTaxi.ts b/apps/web/app/_utils/openKakaoTaxi/openKakaoTaxi.ts new file mode 100644 index 00000000..ebcb13ab --- /dev/null +++ b/apps/web/app/_utils/openKakaoTaxi/openKakaoTaxi.ts @@ -0,0 +1,42 @@ +import { addToast } from '@heroui/react' + +interface OpenKakaoTaxiParams { + latitude: number + longitude: number + placeName?: string +} + +/** + * 카카오택시 앱으로 특정 목적지를 설정하는 딥링크 함수 + * - 모바일: 카카오택시 앱이 설치되어 있으면 앱 실행, 없으면 앱스토어로 이동 + * - 데스크톱: 카카오택시 앱은 모바일 전용이므로 토스트 메시지로 안내 + */ +export const openKakaoTaxi = ({ + latitude, + longitude, + placeName, +}: OpenKakaoTaxiParams): void => { + // 카카오택시 딥링크 URL 스킴 + const appScheme = `kakaot://taxi?dest_lat=${latitude}&dest_lng=${longitude}&end_name=${encodeURIComponent(placeName || '목적지')}` + + const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) + + if (isMobile) { + // 모바일: 딥링크 시도 + window.location.href = appScheme + + // 앱이 설치되지 않은 경우를 대비한 타임아웃 (2.5초 후 스토어로 이동) + setTimeout(() => { + const isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent) + const storeUrl = isIOS + ? 'https://apps.apple.com/kr/app/kakaotaxi/id981110422' + : 'https://play.google.com/store/apps/details?id=com.kakao.taxi' + + window.location.href = storeUrl + }, 2500) + } else { + addToast({ + title: '카카오택시 앱은 모바일에서만 이용 가능합니다.', + }) + } +} diff --git a/apps/web/app/places/[id]/_components/Location/Location.tsx b/apps/web/app/places/[id]/_components/Location/Location.tsx index 5a2300d4..84ce6bdb 100644 --- a/apps/web/app/places/[id]/_components/Location/Location.tsx +++ b/apps/web/app/places/[id]/_components/Location/Location.tsx @@ -4,7 +4,9 @@ import { type Coord, toLatLng } from '@/map/_utils/toLatLng' import { PlaceMarker } from '@/map/_components/Marker' import { Column } from '@repo/ui/components/Layout' import { openNaverMap } from '@/_utils/openNaverMap' +import { openKakaoTaxi } from '@/_utils/openKakaoTaxi' import Image from 'next/image' +import { cn } from '@repo/ui/utils/cn' interface LocationProps { location: Coord @@ -22,10 +24,29 @@ export const Location = ({ location, placeName }: LocationProps) => { }) } + const handleOpenKakaoTaxi = () => { + openKakaoTaxi({ + latitude: location.latitude, + longitude: location.longitude, + placeName, + }) + } + return ( - + + + + { ) } -const OpenNaverMapButton = ({ onClick }: { onClick: VoidFunction }) => ( +interface MapButtonProps { + onClick: VoidFunction + imageSrc: string + alt: string +} + +const MapButton = ({ onClick, imageSrc, alt }: MapButtonProps) => ( ) diff --git a/apps/web/public/images/kakao-taxi-logo.png b/apps/web/public/images/kakao-taxi-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..68d3562e5b5db8fa1e173b411e90de95f7a0df42 GIT binary patch literal 2476 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&zE~)R&4Yzkn2Hfk$L90|U1Z2s2)~TlWVj z7U${W7*a9k?ahr|R}*E9Km5-byXm1$>ugUy)=R2eSnf8gE@5uG@G2}@poIBiD2wh@ zQ5l(8JVnJe&D%_F$Ygj-c;9&bbIif=%7=%4&px~DyPg_@!qaOn7#R+n6=q-%P+?$D z@L*tYn83i$puot$;0Sb96AJ?a3nv2u2hbs-3I-+|7Hqx9yyMQbXFs?6e{=kWB*XtV zhmZfheDdY77m_iK3~N@bJv;yM!_WDP(;5D3*6*%nN@%rY9AvS$`R2EKM_&j66WS-{ zA&{^jA^zvw`poil%PKbQ2T#6yD=FG#Saob`Ztgt)=-Kw}=Mz|EWX~^udh-`F7Vge{ z`sL-@=NFA57}wvopA)yY-UO)pt^IF9S-bycAVXdroc!|jqjx~{2Z1?iQ01&BY1@X= zvOxbVXZLqI?@{?V$?&aRMBluF^+jK5?e^AuulUk4W%1*mFF60SGDHNP-uxBf6HOrN zqVSLYJ(@oz1B;N+l46j>>u9MxAZhYK&bGbfhE*&K1)G8O_GpDV6dD#^q?5Sq|9*aV SpB32rV(@hJb6Mw<&;$U7g@y$H literal 0 HcmV?d00001 From bab77cc440da9a304964790650c54673fe2acc25 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Thu, 19 Feb 2026 00:31:58 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20MapButton=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=EC=9D=98=20=EC=9D=B4=EB=AF=B8=EC=A7=80?= =?UTF-8?q?=EC=97=90=20rounded-sm=20=ED=81=B4=EB=9E=98=EC=8A=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 --- .../web/app/places/[id]/_components/Location/Location.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/web/app/places/[id]/_components/Location/Location.tsx b/apps/web/app/places/[id]/_components/Location/Location.tsx index 84ce6bdb..058d0bf0 100644 --- a/apps/web/app/places/[id]/_components/Location/Location.tsx +++ b/apps/web/app/places/[id]/_components/Location/Location.tsx @@ -80,6 +80,12 @@ const MapButton = ({ onClick, imageSrc, alt }: MapButtonProps) => ( )} onClick={onClick} > - {alt} + {alt} ) From e5b6df0414865db219a00b2c2eeafe5026653e86 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Thu, 19 Feb 2026 00:39:29 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20=EB=84=A4=EC=9D=B4=EB=B2=84=20?= =?UTF-8?q?=EC=A7=80=EB=8F=84=20=EB=94=A5=EB=A7=81=ED=81=AC=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=95=B1=20=EC=8A=A4=ED=82=B4=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20=EB=B0=8F=20=EC=9B=B9=20=ED=8F=B4=EB=B0=B1=20=ED=83=80?= =?UTF-8?q?=EC=9E=84=EC=95=84=EC=9B=83=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/app/_utils/openNaverMap/openNaverMap.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/apps/web/app/_utils/openNaverMap/openNaverMap.ts b/apps/web/app/_utils/openNaverMap/openNaverMap.ts index a9be8e8b..3d5a1bb4 100644 --- a/apps/web/app/_utils/openNaverMap/openNaverMap.ts +++ b/apps/web/app/_utils/openNaverMap/openNaverMap.ts @@ -15,8 +15,7 @@ export const openNaverMap = ({ placeName, }: OpenNaverMapParams): void => { // 네이버 지도 URL 스킴 (앱) - const appScheme = `nmap://place?lat=${latitude}&lng=${longitude}&name=${encodeURIComponent(placeName || '위치')}&appname=com.matzip` - + const appScheme = `nmap://place?lat=${latitude}&lng=${longitude}&name=${encodeURIComponent(placeName || '위치')}` // 네이버 지도 웹 URL (폴백) const webUrl = `https://map.naver.com/p/search/${encodeURIComponent(placeName || '')}?c=${longitude},${latitude},18,0,0,0,dh` @@ -25,11 +24,6 @@ export const openNaverMap = ({ if (isMobile) { // 모바일: 딥링크 시도 window.location.href = appScheme - - // 앱이 설치되지 않은 경우를 대비한 타임아웃 (2.5초 후 웹으로 폴백) - setTimeout(() => { - window.location.href = webUrl - }, 2500) } else { // 데스크톱: 웹 페이지로 바로 이동 window.open(webUrl, '_blank') From e0313f5f5d76e705592dc1f96d9d43a2e94303c8 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Thu, 19 Feb 2026 00:59:04 +0900 Subject: [PATCH 5/8] =?UTF-8?q?refactor:=20=EB=94=A5=EB=A7=81=ED=81=AC=20?= =?UTF-8?q?=EA=B3=B5=ED=86=B5=20=EB=A1=9C=EC=A7=81=EC=9D=84=20openDeepLink?= =?UTF-8?q?=20=EC=9C=A0=ED=8B=B8=20=ED=95=A8=EC=88=98=EB=A1=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20-=20openDeepLink=20=EC=9C=A0=ED=8B=B8=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=B6=94=EA=B0=80:=20=EC=95=B1=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=20=EA=B0=90=EC=A7=80=20=EB=B0=8F=20=ED=8F=B4=EB=B0=B1?= =?UTF-8?q?=20=EC=B2=98=EB=A6=AC=20=EB=A1=9C=EC=A7=81=20=EC=BA=A1=EC=8A=90?= =?UTF-8?q?=ED=99=94=20-=20visibilitychange=20=EC=9D=B4=EB=B2=A4=ED=8A=B8?= =?UTF-8?q?=EB=A1=9C=20=EC=95=B1=20=EC=8B=A4=ED=96=89=20=EA=B0=90=EC=A7=80?= =?UTF-8?q?=20=ED=9B=84=20=ED=83=80=EC=9E=84=EC=95=84=EC=9B=83=20=EC=B7=A8?= =?UTF-8?q?=EC=86=8C=20->=20=EC=95=B1=EC=9D=B4=20=EC=97=B4=EB=A6=AC?= =?UTF-8?q?=EB=A9=B4=20=ED=8F=B4=EB=B0=B1=20URL=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/app/_utils/openDeepLink/index.ts | 1 + .../app/_utils/openDeepLink/openDeepLink.ts | 39 +++++++++++++++++++ .../app/_utils/openKakaoTaxi/openKakaoTaxi.ts | 17 +++----- .../app/_utils/openNaverMap/openNaverMap.ts | 7 ++-- 4 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 apps/web/app/_utils/openDeepLink/index.ts create mode 100644 apps/web/app/_utils/openDeepLink/openDeepLink.ts diff --git a/apps/web/app/_utils/openDeepLink/index.ts b/apps/web/app/_utils/openDeepLink/index.ts new file mode 100644 index 00000000..44a9818e --- /dev/null +++ b/apps/web/app/_utils/openDeepLink/index.ts @@ -0,0 +1 @@ +export { openDeepLink } from './openDeepLink' diff --git a/apps/web/app/_utils/openDeepLink/openDeepLink.ts b/apps/web/app/_utils/openDeepLink/openDeepLink.ts new file mode 100644 index 00000000..d39ab6ed --- /dev/null +++ b/apps/web/app/_utils/openDeepLink/openDeepLink.ts @@ -0,0 +1,39 @@ +interface OpenDeepLinkParams { + appScheme: string + fallbackUrl: string +} + +/** + * 딥링크 실행 유틸 함수 + * - 앱이 설치되어 있으면 앱 실행 + * - 앱이 없으면 2.5초 후 fallbackUrl로 이동 + * - 앱 실행 시 페이지가 백그라운드로 가면 fallback 취소 + */ +export const openDeepLink = ({ + appScheme, + fallbackUrl, +}: OpenDeepLinkParams): void => { + const startTime = Date.now() + + // 페이지가 백그라운드로 가면 앱이 실행된 것으로 간주 + const handleVisibilityChange = () => { + if (document.hidden) { + // 앱이 실행되어 페이지가 숨겨짐 + clearTimeout(fallbackTimeout) + document.removeEventListener('visibilitychange', handleVisibilityChange) + } + } + + document.addEventListener('visibilitychange', handleVisibilityChange) + + // 앱이 설치되지 않은 경우를 대비한 타임아웃 + const fallbackTimeout = setTimeout(() => { + document.removeEventListener('visibilitychange', handleVisibilityChange) + // 페이지가 포그라운드 상태로 유지되었다면 앱이 없는 것으로 간주 + if (!document.hidden && Date.now() - startTime >= 2500) { + window.location.href = fallbackUrl + } + }, 2500) + + window.location.href = appScheme +} diff --git a/apps/web/app/_utils/openKakaoTaxi/openKakaoTaxi.ts b/apps/web/app/_utils/openKakaoTaxi/openKakaoTaxi.ts index ebcb13ab..8ea09b26 100644 --- a/apps/web/app/_utils/openKakaoTaxi/openKakaoTaxi.ts +++ b/apps/web/app/_utils/openKakaoTaxi/openKakaoTaxi.ts @@ -1,4 +1,5 @@ import { addToast } from '@heroui/react' +import { openDeepLink } from '../openDeepLink' interface OpenKakaoTaxiParams { latitude: number @@ -22,18 +23,12 @@ export const openKakaoTaxi = ({ const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) if (isMobile) { - // 모바일: 딥링크 시도 - window.location.href = appScheme + const isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent) + const storeUrl = isIOS + ? 'https://apps.apple.com/kr/app/kakaotaxi/id981110422' + : 'https://play.google.com/store/apps/details?id=com.kakao.taxi' - // 앱이 설치되지 않은 경우를 대비한 타임아웃 (2.5초 후 스토어로 이동) - setTimeout(() => { - const isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent) - const storeUrl = isIOS - ? 'https://apps.apple.com/kr/app/kakaotaxi/id981110422' - : 'https://play.google.com/store/apps/details?id=com.kakao.taxi' - - window.location.href = storeUrl - }, 2500) + openDeepLink({ appScheme, fallbackUrl: storeUrl }) } else { addToast({ title: '카카오택시 앱은 모바일에서만 이용 가능합니다.', diff --git a/apps/web/app/_utils/openNaverMap/openNaverMap.ts b/apps/web/app/_utils/openNaverMap/openNaverMap.ts index 3d5a1bb4..0fbeb4dc 100644 --- a/apps/web/app/_utils/openNaverMap/openNaverMap.ts +++ b/apps/web/app/_utils/openNaverMap/openNaverMap.ts @@ -1,3 +1,5 @@ +import { openDeepLink } from '../openDeepLink' + interface OpenNaverMapParams { latitude: number longitude: number @@ -6,7 +8,7 @@ interface OpenNaverMapParams { /** * 네이버 지도 앱으로 특정 위치를 여는 딥링크 함수 - * - 모바일: 네이버 지도 앱이 설치되어 있으면 앱 실행, 없으면 앱스토어로 이동 + * - 모바일: 네이버 지도 앱이 설치되어 있으면 앱 실행, 없으면 웹으로 이동 * - 데스크톱: 네이버 지도 웹 페이지로 이동 */ export const openNaverMap = ({ @@ -22,8 +24,7 @@ export const openNaverMap = ({ const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) if (isMobile) { - // 모바일: 딥링크 시도 - window.location.href = appScheme + openDeepLink({ appScheme, fallbackUrl: webUrl }) } else { // 데스크톱: 웹 페이지로 바로 이동 window.open(webUrl, '_blank') From 6cf0c634d99889ad877e4f4b817a8f4da1d3b5f6 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Thu, 19 Feb 2026 01:16:17 +0900 Subject: [PATCH 6/8] =?UTF-8?q?feat:=20PlacePreview=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EB=8A=94=20Location=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=88=ED=8A=B8=20=EB=94=B0=EB=A1=9C=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Step/PlacePreview/Location.tsx | 28 +++++++++++++++++++ .../Step/PlacePreview/PlacePreview.tsx | 3 +- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 apps/web/app/places/new/_components/Step/PlacePreview/Location.tsx diff --git a/apps/web/app/places/new/_components/Step/PlacePreview/Location.tsx b/apps/web/app/places/new/_components/Step/PlacePreview/Location.tsx new file mode 100644 index 00000000..5c156ec1 --- /dev/null +++ b/apps/web/app/places/new/_components/Step/PlacePreview/Location.tsx @@ -0,0 +1,28 @@ +import { useState } from 'react' +import { Container, NaverMap } from 'react-naver-maps' +import { type Coord, toLatLng } from '@/map/_utils/toLatLng' +import { PlaceMarker } from '@/map/_components/Marker' +import { Column } from '@repo/ui/components/Layout' + +interface LocationProps { + location: Coord +} + +export const Location = ({ location }: LocationProps) => { + const [, setMap] = useState(null) + + return ( + + + + + + + + ) +} 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 40c75d42..a0d1246e 100644 --- a/apps/web/app/places/new/_components/Step/PlacePreview/PlacePreview.tsx +++ b/apps/web/app/places/new/_components/Step/PlacePreview/PlacePreview.tsx @@ -4,7 +4,8 @@ import { useFormContext } from 'react-hook-form' import type { NewPlaceRequest } from '@/_apis/schemas/place' import { usePlaceQueries } from '@/_apis/queries/place' import { Carousel } from '@repo/ui/components/Carousel' -import { Location, Menus } from '@/places/[id]/_components' +import { Menus } from '@/places/[id]/_components' +import { Location } from './Location' import { Text } from '@repo/ui/components/Text' import { Button } from '@repo/ui/components/Button' import { Column, Flex, VerticalScrollArea } from '@repo/ui/components/Layout' From 877eb015df372a047fd42802a0bc0fc3a7726d00 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Thu, 19 Feb 2026 01:29:16 +0900 Subject: [PATCH 7/8] =?UTF-8?q?refactor:=20=EB=94=A5=EB=A7=81=ED=81=AC=20?= =?UTF-8?q?=EC=9C=A0=ED=8B=B8=20=ED=95=A8=EC=88=98=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81=20=EB=B0=8F=20=EB=94=94=EB=B0=94=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20=EA=B0=90=EC=A7=80=20=EB=A1=9C=EC=A7=81=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20-=20device=20=EC=9C=A0=ED=8B=B8=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=B6=94=EA=B0=80:=20isMobileDevice,=20isIOSDevice?= =?UTF-8?q?=20=ED=95=A8=EC=88=98=EB=A1=9C=20=EC=A4=91=EB=B3=B5=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20-=20=EA=B0=81=20URL=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/app/_utils/device/device.ts | 16 ++++++++++ apps/web/app/_utils/device/index.ts | 1 + .../app/_utils/openDeepLink/openDeepLink.ts | 10 +++++-- .../app/_utils/openKakaoTaxi/openKakaoTaxi.ts | 30 +++++++++---------- .../app/_utils/openNaverMap/openNaverMap.ts | 26 ++++++++-------- .../app/requests/[id]/RequestDetailPage.tsx | 2 +- 6 files changed, 52 insertions(+), 33 deletions(-) create mode 100644 apps/web/app/_utils/device/device.ts create mode 100644 apps/web/app/_utils/device/index.ts diff --git a/apps/web/app/_utils/device/device.ts b/apps/web/app/_utils/device/device.ts new file mode 100644 index 00000000..4416a577 --- /dev/null +++ b/apps/web/app/_utils/device/device.ts @@ -0,0 +1,16 @@ +/** + * 모바일 디바이스 감지 정규식 + */ +const MOBILE_REGEX = /iPhone|iPad|iPod|Android/i +const IOS_REGEX = /iPhone|iPad|iPod/i + +/** + * 현재 디바이스가 모바일인지 확인 + */ +export const isMobileDevice = (): boolean => + MOBILE_REGEX.test(navigator.userAgent) + +/** + * 현재 디바이스가 iOS인지 확인 + */ +export const isIOSDevice = (): boolean => IOS_REGEX.test(navigator.userAgent) diff --git a/apps/web/app/_utils/device/index.ts b/apps/web/app/_utils/device/index.ts new file mode 100644 index 00000000..f6ef6e0c --- /dev/null +++ b/apps/web/app/_utils/device/index.ts @@ -0,0 +1 @@ +export { isMobileDevice, isIOSDevice } from './device' diff --git a/apps/web/app/_utils/openDeepLink/openDeepLink.ts b/apps/web/app/_utils/openDeepLink/openDeepLink.ts index d39ab6ed..5a5a76ac 100644 --- a/apps/web/app/_utils/openDeepLink/openDeepLink.ts +++ b/apps/web/app/_utils/openDeepLink/openDeepLink.ts @@ -1,17 +1,21 @@ interface OpenDeepLinkParams { appScheme: string fallbackUrl: string + timeout?: number } +const DEEPLINK_TIMEOUT = 2500 + /** * 딥링크 실행 유틸 함수 * - 앱이 설치되어 있으면 앱 실행 - * - 앱이 없으면 2.5초 후 fallbackUrl로 이동 + * - 앱이 없으면 timeout 이후 fallbackUrl로 이동 * - 앱 실행 시 페이지가 백그라운드로 가면 fallback 취소 */ export const openDeepLink = ({ appScheme, fallbackUrl, + timeout = DEEPLINK_TIMEOUT, }: OpenDeepLinkParams): void => { const startTime = Date.now() @@ -30,10 +34,10 @@ export const openDeepLink = ({ const fallbackTimeout = setTimeout(() => { document.removeEventListener('visibilitychange', handleVisibilityChange) // 페이지가 포그라운드 상태로 유지되었다면 앱이 없는 것으로 간주 - if (!document.hidden && Date.now() - startTime >= 2500) { + if (!document.hidden && Date.now() - startTime >= timeout) { window.location.href = fallbackUrl } - }, 2500) + }, timeout) window.location.href = appScheme } diff --git a/apps/web/app/_utils/openKakaoTaxi/openKakaoTaxi.ts b/apps/web/app/_utils/openKakaoTaxi/openKakaoTaxi.ts index 8ea09b26..0bf786f8 100644 --- a/apps/web/app/_utils/openKakaoTaxi/openKakaoTaxi.ts +++ b/apps/web/app/_utils/openKakaoTaxi/openKakaoTaxi.ts @@ -1,9 +1,9 @@ import { addToast } from '@heroui/react' import { openDeepLink } from '../openDeepLink' +import { isMobileDevice, isIOSDevice } from '../device' +import { Coord } from '@/map/_utils/toLatLng' -interface OpenKakaoTaxiParams { - latitude: number - longitude: number +interface OpenKakaoTaxiParams extends Coord { placeName?: string } @@ -15,23 +15,21 @@ interface OpenKakaoTaxiParams { export const openKakaoTaxi = ({ latitude, longitude, - placeName, + placeName = '목적지', }: OpenKakaoTaxiParams): void => { - // 카카오택시 딥링크 URL 스킴 - const appScheme = `kakaot://taxi?dest_lat=${latitude}&dest_lng=${longitude}&end_name=${encodeURIComponent(placeName || '목적지')}` - - const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) - - if (isMobile) { - const isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent) - const storeUrl = isIOS - ? 'https://apps.apple.com/kr/app/kakaotaxi/id981110422' - : 'https://play.google.com/store/apps/details?id=com.kakao.taxi' - - openDeepLink({ appScheme, fallbackUrl: storeUrl }) + if (isMobileDevice()) { + const urls = buildKakaoTaxiUrls({ latitude, longitude }, placeName) + openDeepLink({ appScheme: urls.app, fallbackUrl: urls.store }) } else { addToast({ title: '카카오택시 앱은 모바일에서만 이용 가능합니다.', }) } } + +const buildKakaoTaxiUrls = (coords: Coord, placeName: string) => ({ + app: `kakaot://taxi?dest_lat=${coords.latitude}&dest_lng=${coords.longitude}&end_name=${encodeURIComponent(placeName)}`, + store: isIOSDevice() + ? 'https://apps.apple.com/kr/app/kakaotaxi/id981110422' + : 'https://play.google.com/store/apps/details?id=com.kakao.taxi', +}) diff --git a/apps/web/app/_utils/openNaverMap/openNaverMap.ts b/apps/web/app/_utils/openNaverMap/openNaverMap.ts index 0fbeb4dc..5602ec08 100644 --- a/apps/web/app/_utils/openNaverMap/openNaverMap.ts +++ b/apps/web/app/_utils/openNaverMap/openNaverMap.ts @@ -1,8 +1,8 @@ import { openDeepLink } from '../openDeepLink' +import { isMobileDevice } from '../device' +import { Coord } from '@/map/_utils/toLatLng' -interface OpenNaverMapParams { - latitude: number - longitude: number +interface OpenNaverMapParams extends Coord { placeName?: string } @@ -14,19 +14,19 @@ interface OpenNaverMapParams { export const openNaverMap = ({ latitude, longitude, - placeName, + placeName = '공주대학교', }: OpenNaverMapParams): void => { - // 네이버 지도 URL 스킴 (앱) - const appScheme = `nmap://place?lat=${latitude}&lng=${longitude}&name=${encodeURIComponent(placeName || '위치')}` - // 네이버 지도 웹 URL (폴백) - const webUrl = `https://map.naver.com/p/search/${encodeURIComponent(placeName || '')}?c=${longitude},${latitude},18,0,0,0,dh` + const urls = buildNaverMapUrls({ latitude, longitude }, placeName) - const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) - - if (isMobile) { - openDeepLink({ appScheme, fallbackUrl: webUrl }) + if (isMobileDevice()) { + openDeepLink({ appScheme: urls.app, fallbackUrl: urls.web }) } else { // 데스크톱: 웹 페이지로 바로 이동 - window.open(webUrl, '_blank') + window.open(urls.web, '_blank') } } + +const buildNaverMapUrls = (coords: Coord, placeName: string) => ({ + app: `nmap://place?lat=${coords.latitude}&lng=${coords.longitude}&name=${encodeURIComponent(placeName)}&appname=com.matzip`, + web: `https://map.naver.com/p/search/${encodeURIComponent(placeName)}?c=${coords.longitude},${coords.latitude},18,0,0,0,dh`, +}) diff --git a/apps/web/app/requests/[id]/RequestDetailPage.tsx b/apps/web/app/requests/[id]/RequestDetailPage.tsx index 8edcf671..89aac796 100644 --- a/apps/web/app/requests/[id]/RequestDetailPage.tsx +++ b/apps/web/app/requests/[id]/RequestDetailPage.tsx @@ -56,7 +56,7 @@ export const RequestDetailPage = ({ id }: { id: string }) => {
- +
From a3636f71216b7a6d49117a63136c69f88f5b7f94 Mon Sep 17 00:00:00 2001 From: leeleeleeleejun Date: Thu, 19 Feb 2026 01:52:52 +0900 Subject: [PATCH 8/8] =?UTF-8?q?fix:=20Location=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=EC=9D=98=20=EC=A7=80=EB=8F=84=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=ED=91=9C=EC=8B=9C=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Container에 relative 포지셔닝 추가 - 버튼 컨테이너에 z-10 추가하여 지도 위에 표시되도록 개선 - MapButton에 type='button' 명시하여 폼 제출 방지 --- apps/web/app/places/[id]/_components/Location/Location.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/web/app/places/[id]/_components/Location/Location.tsx b/apps/web/app/places/[id]/_components/Location/Location.tsx index 058d0bf0..b716709d 100644 --- a/apps/web/app/places/[id]/_components/Location/Location.tsx +++ b/apps/web/app/places/[id]/_components/Location/Location.tsx @@ -34,8 +34,8 @@ export const Location = ({ location, placeName }: LocationProps) => { return ( - - + + (