"use client"; import { useEffect, useState } from "react"; import { api, getToken } from "@/lib/api"; import type { Restaurant, VideoLink } from "@/lib/api"; import ReviewSection from "@/components/ReviewSection"; import MemoSection from "@/components/MemoSection"; import { RestaurantDetailSkeleton } from "@/components/Skeleton"; import Icon from "@/components/Icon"; interface RestaurantDetailProps { restaurant: Restaurant; onClose: () => void; } // #319 — 외부 지도 검색용 쿼리 빌더. region이 더미('나라|' 형태)면 무시. function buildSearchQuery(r: Restaurant): string { if (r.address) return `${r.name} ${r.address}`; if (r.region) { const cleanRegion = r.region.replace(/\|/g, " ").trim(); // 빈 토큰만 남는 경우 (예: '한국' 또는 '한국|') → name만 사용 if (cleanRegion && cleanRegion !== "한국") return `${r.name} ${cleanRegion}`; } return r.name; } // 좌표 기반 한국 판정 (WGS84). KR bbox 대략 33~38.7°N, 124~132°E. // 좌표 없으면 region 첫 토큰으로 fallback (구 데이터 호환). function isKoreaRestaurant(r: Restaurant): boolean { if (r.latitude != null && r.longitude != null) { return r.latitude >= 33 && r.latitude <= 38.7 && r.longitude >= 124 && r.longitude <= 132; } return !r.region || r.region.split("|")[0] === "한국"; } export default function RestaurantDetail({ restaurant, onClose, }: RestaurantDetailProps) { const [videos, setVideos] = useState([]); const [loading, setLoading] = useState(true); const [favorited, setFavorited] = useState(false); const [favLoading, setFavLoading] = useState(false); useEffect(() => { let cancelled = false; setLoading(true); api .getRestaurantVideos(restaurant.id) .then((v) => { if (!cancelled) setVideos(v); }) .catch(() => { if (!cancelled) setVideos([]); }) .finally(() => { if (!cancelled) setLoading(false); }); if (getToken()) { api.getFavoriteStatus(restaurant.id) .then((r) => { if (!cancelled) setFavorited(r.favorited); }) .catch(() => {}); } return () => { cancelled = true; }; }, [restaurant.id]); const handleToggleFavorite = async () => { if (!getToken()) return; setFavLoading(true); try { const res = await api.toggleFavorite(restaurant.id); setFavorited(res.favorited); } catch { /* ignore */ } finally { setFavLoading(false); } }; return (

{restaurant.name}

{getToken() && ( )} {restaurant.business_status === "CLOSED_PERMANENTLY" && ( 폐업 )} {restaurant.business_status === "CLOSED_TEMPORARILY" && ( 임시휴업 )}
{restaurant.rating && (
Google {"★".repeat(Math.round(restaurant.rating))} {restaurant.rating} {restaurant.rating_count && ( ({restaurant.rating_count.toLocaleString()}) )}
)}
{restaurant.cuisine_type && (

종류 {restaurant.cuisine_type}

)} {restaurant.address && (

주소 {restaurant.address}

)} {restaurant.region && (

지역 {restaurant.region}

)} {restaurant.price_range && (

가격대 {restaurant.price_range}

)} {restaurant.phone && (

전화{" "} {restaurant.phone}

)} {restaurant.google_place_id && (

{isKoreaRestaurant(restaurant) ? ( <> 네이버 지도에서 보기 Google Maps ) : ( Google Maps에서 보기 )}

)}
{restaurant.tabling_url && restaurant.tabling_url !== "NONE" && ( T 테이블링에서 줄서기 )} {restaurant.catchtable_url && restaurant.catchtable_url !== "NONE" && ( C 캐치테이블에서 예약하기 )}

관련 영상

{loading ? (
{[1, 2].map((i) => (
))}
) : videos.length === 0 ? (

관련 영상이 없습니다

) : (
{videos.map((v) => (
{v.channel_name && ( {v.channel_name} )} {v.published_at && ( {v.published_at.slice(0, 10)} )}
{v.title} {v.foods_mentioned?.length > 0 && (
{v.foods_mentioned.map((f, i) => ( {f} ))}
)} {v.evaluation?.text && (

{v.evaluation.text}

)} {v.guests?.length > 0 && (

게스트: {v.guests.join(", ")}

)}
))}
)}
{videos.length > 0 && (

더 자세한 내용은 영상에서 확인하실 수 있습니다.

맛집을 소개해주신 크리에이터를 구독과 좋아요로 응원해주세요!

)}
); }