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',