Skip to content

Commit ac34571

Browse files
committed
refactor(planner): useSearchPlace 훅으로 주변 식당 데이터 가져오기 로직 변경 및 관련 타입 수정
1 parent f452c60 commit ac34571

2 files changed

Lines changed: 26 additions & 53 deletions

File tree

src/components/planner/sidebar/PlannerNearbyRestaurants.tsx

Lines changed: 24 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
"use client";
22
import { Button } from "@/components/ui/button";
3-
import { getNearbyRestaurants } from "@/lib/api/planner/location.client";
3+
import { useSearchPlace } from "@/hooks/planner/useSearchPlace";
44
import { cn } from "@/lib/utils";
55
import { NearbyPlaces, ScheduleDetail } from "@/types/planner";
66
import { formatDistance } from "@/utils/helpers/formatters";
77
import { calculateDistance } from "@/utils/helpers/geolocation";
88
import { Loader2Icon, ChevronDownIcon } from "lucide-react";
99
import Link from "next/link";
10-
import { useEffect, useState, useTransition } from "react";
10+
import { useState } from "react";
1111

1212
const INITIAL_DISPLAY_COUNT = 3;
1313

@@ -16,69 +16,44 @@ export default function PlannerNearbyRestaurants({
1616
}: {
1717
concertSchedule: ScheduleDetail;
1818
}) {
19-
const [isPending, startTransition] = useTransition();
20-
const [nearbyRestaurants, setNearbyRestaurants] = useState<NearbyPlaces[]>([]);
21-
const [isExpanded, setIsExpanded] = useState(false);
19+
const coords = { lat: concertSchedule.locationLat!, lon: concertSchedule.locationLon! };
2220

23-
useEffect(() => {
24-
let cancelled = false;
25-
const fetchNearbyRestaurants = async () => {
26-
const data = await getNearbyRestaurants(
27-
concertSchedule.locationLon!,
28-
concertSchedule.locationLat!
29-
);
30-
if (cancelled) return;
31-
startTransition(() => {
32-
setNearbyRestaurants(data);
33-
});
34-
};
35-
fetchNearbyRestaurants();
36-
return () => {
37-
cancelled = true;
38-
};
39-
}, [concertSchedule.locationLon, concertSchedule.locationLat]);
21+
const { results, isLoading, stableCoords } = useSearchPlace("", coords, "MEAL");
22+
const [isExpanded, setIsExpanded] = useState(false);
4023

41-
const displayedRestaurants = isExpanded
42-
? nearbyRestaurants
43-
: nearbyRestaurants.slice(0, INITIAL_DISPLAY_COUNT);
24+
const visibleResults = isExpanded ? results : results.slice(0, INITIAL_DISPLAY_COUNT);
4425

4526
return (
4627
<div className="bg-bg-main border-border flex-1 lg:overflow-hidden lg:border lg:p-6">
4728
<h4 className="text-base font-semibold">주변 식당</h4>
48-
{isPending ? (
29+
{isLoading ? (
4930
<div className="flex items-center justify-center py-10">
5031
<Loader2Icon className="text-muted-foreground animate-spin" />
5132
</div>
52-
) : nearbyRestaurants.length === 0 ? (
33+
) : results.length === 0 ? (
5334
<div className="text-text-sub flex items-center justify-center py-10 text-sm">
5435
주변에 식당이 없습니다.
5536
</div>
5637
) : (
5738
<>
58-
<ul
59-
className={cn(
60-
"space-y-3",
61-
isExpanded && "scrollbar-hide lg:max-h-[300px] lg:overflow-y-auto lg:pr-2"
62-
)}
63-
>
64-
{displayedRestaurants.map((restaurant) => {
65-
const distance = calculateDistance(
66-
concertSchedule.locationLat!,
67-
concertSchedule.locationLon!,
68-
restaurant.y,
69-
restaurant.x
70-
);
39+
<ul className={cn("space-y-3", isExpanded && "lg:pr-2")}>
40+
{visibleResults.map((place: NearbyPlaces) => {
41+
const distance = stableCoords
42+
? calculateDistance(
43+
stableCoords.lat,
44+
stableCoords.lon,
45+
Number(place.y),
46+
Number(place.x)
47+
)
48+
: 0;
7149

7250
return (
73-
<li
74-
key={restaurant.place_url}
75-
className="bg-bg-sub flex flex-col gap-1 rounded-xl p-4"
76-
>
77-
<strong>{restaurant.place_name}</strong>
78-
<span className="text-text-sub text-xs">{restaurant.road_address_name}</span>
51+
<li key={place.place_url} className="bg-bg-sub flex flex-col gap-1 rounded-xl p-4">
52+
<strong>{place.place_name}</strong>
53+
<span className="text-text-sub text-xs">{place.road_address_name}</span>
7954
<div className="flex justify-between text-xs">
8055
<Link
81-
href={restaurant.place_url}
56+
href={place.place_url}
8257
target="_blank"
8358
rel="noopener noreferrer"
8459
className="text-muted-foreground underline"
@@ -91,7 +66,7 @@ export default function PlannerNearbyRestaurants({
9166
);
9267
})}
9368
</ul>
94-
{nearbyRestaurants.length > INITIAL_DISPLAY_COUNT && (
69+
{results.length > INITIAL_DISPLAY_COUNT && (
9570
<Button
9671
variant="outline"
9772
className="w-full cursor-pointer gap-2"
@@ -100,9 +75,7 @@ export default function PlannerNearbyRestaurants({
10075
<ChevronDownIcon
10176
className={cn("size-4 transition-transform", isExpanded && "rotate-180")}
10277
/>
103-
{isExpanded
104-
? "숨기기"
105-
: `${nearbyRestaurants.length - INITIAL_DISPLAY_COUNT}개 더보기`}
78+
{isExpanded ? "숨기기" : `${results.length - INITIAL_DISPLAY_COUNT}개 더보기`}
10679
</Button>
10780
)}
10881
</>

src/lib/api/planner/location.client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ResponseData } from "@/types/api";
2-
import { NearbyPlaces, UserPlace } from "@/types/planner";
2+
import { NearbyPlaces, SearchPlace, UserPlace } from "@/types/planner";
33
import ClientApi from "@/utils/helpers/clientApi";
44

55
/**
@@ -115,7 +115,7 @@ export const deleteUserLocation = async (): Promise<void> => {
115115
* @param {string} query - 검색 키워드
116116
* @returns {Promise<any[]>} 검색된 장소 목록
117117
*/
118-
export const searchPlaceByKeyword = async (query: string) => {
118+
export const searchPlaceByKeyword = async (query: string): Promise<SearchPlace[]> => {
119119
const res = await fetch(`/api/location?query=${encodeURIComponent(query)}`);
120120

121121
if (!res.ok) throw new Error("장소 검색 실패");

0 commit comments

Comments
 (0)