diff --git a/src/features/map/collaboration/CollabPinsOverlay.tsx b/src/features/map/collaboration/CollabPinsOverlay.tsx index 38c40843..6f4e7b68 100644 --- a/src/features/map/collaboration/CollabPinsOverlay.tsx +++ b/src/features/map/collaboration/CollabPinsOverlay.tsx @@ -3,9 +3,10 @@ import { useEffect, useRef } from 'react'; import styled from '@emotion/styled'; import { HugeiconsIcon } from '@hugeicons/react'; -import { Location01Icon, Cancel01Icon, UserMultiple02Icon } from '@hugeicons/core-free-icons'; +import { Location01Icon, Cancel01Icon, UserMultiple02Icon, Login01Icon } from '@hugeicons/core-free-icons'; import { toast } from 'sonner'; import { useSelf } from '@liveblocks/react'; +import { useAuth } from '@/features/auth'; import { useMapStore } from '../hooks/useMapStore'; import { useCollabPins } from './useCollabPins'; import { ringShadow, palette } from '@/design-system/tokens'; @@ -152,6 +153,7 @@ export function CollabPinsOverlay() { const viewportItems = useMapStore((s) => s.viewportItems); const detailId = useMapStore((s) => s.detailId); const me = useSelf(); + const { isLoggedIn, loginWithKakao } = useAuth(); const { pins, addPin, removePin } = useCollabPins(); // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -280,6 +282,15 @@ export function CollabPinsOverlay() { function handleAddPin() { if (!selectedPlace) return; + if (!isLoggedIn) { + toast('로그인이 필요해요', { + icon: , + description: '핀 공유는 로그인 후 사용할 수 있어요.', + duration: 5000, + action: { label: '로그인하기', onClick: loginWithKakao }, + }); + return; + } const pin: CollabPin = { placeId: selectedPlace.id, placeName: selectedPlace.name, diff --git a/src/features/map/components/InfoPlaceList.tsx b/src/features/map/components/InfoPlaceList.tsx index e1fb2ec0..3c84cf6b 100644 --- a/src/features/map/components/InfoPlaceList.tsx +++ b/src/features/map/components/InfoPlaceList.tsx @@ -241,10 +241,14 @@ export default function InfoPlaceList() { const requestSnapshotId = store.listSnapshotId; store.setIsListLoading(true); + const requestUserLocation = store.userLocation; listInfoPlaces({ category: requestCategory, regionCode: requestRegionCode, cursor, + ...(requestUserLocation + ? { sort: 'DISTANCE', lat: requestUserLocation.lat, lng: requestUserLocation.lng } + : {}), signal: ctrl.signal, }) .then((page) => { diff --git a/src/features/map/hooks/useInfoMapData.ts b/src/features/map/hooks/useInfoMapData.ts index 93035de4..ee41a301 100644 --- a/src/features/map/hooks/useInfoMapData.ts +++ b/src/features/map/hooks/useInfoMapData.ts @@ -65,6 +65,7 @@ export function useInfoMapData(enabled = true) { const mode = useMapStore((s) => s.mode); const infoCategory = useMapStore((s) => s.infoCategory); const infoRegionCode = useMapStore((s) => s.infoRegionCode); + const userLocation = useMapStore((s) => s.userLocation); const committedViewport = useMapStore((s) => s.committedViewport); const infoListReloadNonce = useMapStore((s) => s.infoListReloadNonce); const infoViewportReloadNonce = useMapStore((s) => s.infoViewportReloadNonce); @@ -98,6 +99,7 @@ export function useInfoMapData(enabled = true) { listInfoPlaces({ category: infoCategory, regionCode: infoRegionCode, + ...(userLocation ? { sort: 'DISTANCE', lat: userLocation.lat, lng: userLocation.lng } : {}), signal: ctrl.signal, timeoutMs, }) @@ -141,7 +143,7 @@ export function useInfoMapData(enabled = true) { }); return () => ctrl.abort(); - }, [enabled, mode, infoCategory, infoRegionCode, infoListReloadNonce]); + }, [enabled, mode, infoCategory, infoRegionCode, userLocation?.lat, userLocation?.lng, infoListReloadNonce]); // ── Viewport ─────────────────────────────────────────────────────────────── useEffect(() => { diff --git a/src/features/map/services/infoMap.service.ts b/src/features/map/services/infoMap.service.ts index 7900c9ff..41b1cf20 100644 --- a/src/features/map/services/infoMap.service.ts +++ b/src/features/map/services/infoMap.service.ts @@ -13,6 +13,9 @@ export interface ListInfoPlacesInput { regionCode?: string | null; cursor?: string | null; limit?: number; + sort?: 'REGION_NAME' | 'NAME' | 'DISTANCE'; + lat?: number | null; + lng?: number | null; signal?: AbortSignal; timeoutMs?: number; } @@ -58,6 +61,11 @@ export async function listInfoPlaces(input: ListInfoPlacesInput): Promise('/map/info/places', { method: 'GET',