diff --git a/backend/routes/schedules.js b/backend/routes/schedules.js index e72e41b..7768abc 100644 --- a/backend/routes/schedules.js +++ b/backend/routes/schedules.js @@ -155,15 +155,29 @@ router.get("/:id", async (req, res) => { return res.status(404).json({ error: "일정을 찾을 수 없습니다." }); } + const schedule = schedules[0]; + // 이미지 조회 const [images] = await pool.query( `SELECT image_url FROM schedule_images WHERE schedule_id = ? ORDER BY sort_order ASC`, [id] ); - - const schedule = schedules[0]; schedule.images = images.map((img) => img.image_url); + // 콘서트 카테고리(id=6)인 경우 같은 제목의 관련 일정들도 조회 + if (schedule.category_id === 6) { + const [relatedSchedules] = await pool.query( + ` + SELECT id, date, time + FROM schedules + WHERE title = ? AND category_id = 6 + ORDER BY date ASC, time ASC + `, + [schedule.title] + ); + schedule.related_dates = relatedSchedules; + } + res.json(schedule); } catch (error) { console.error("일정 조회 오류:", error); diff --git a/frontend/.env b/frontend/.env index 8f9f3d9..6400e98 100644 --- a/frontend/.env +++ b/frontend/.env @@ -1,2 +1,2 @@ -VITE_KAKAO_JS_KEY=5a626e19fbafb33b1eea26f162038ccb +VITE_KAKAO_JS_KEY=84b3c657c3de7d1ca89e1fa33455b8da VITE_KAKAO_REST_KEY=e7a5516bf6cb1b398857789ee2ea6eea diff --git a/frontend/src/pages/pc/public/ScheduleDetail.jsx b/frontend/src/pages/pc/public/ScheduleDetail.jsx index 11396cb..a590b91 100644 --- a/frontend/src/pages/pc/public/ScheduleDetail.jsx +++ b/frontend/src/pages/pc/public/ScheduleDetail.jsx @@ -1,12 +1,12 @@ import { useParams, Link } from 'react-router-dom'; -import { useQuery } from '@tanstack/react-query'; +import { useQuery, keepPreviousData } from '@tanstack/react-query'; import { useEffect, useRef, useState } from 'react'; import { motion } from 'framer-motion'; import { Clock, Calendar, ExternalLink, ChevronRight, Link2, MapPin, Navigation } from 'lucide-react'; import { getSchedule, getXProfile } from '../../../api/public/schedules'; // 카카오맵 SDK 키 -const KAKAO_MAP_KEY = import.meta.env.VITE_KAKAO_MAP_KEY; +const KAKAO_MAP_KEY = import.meta.env.VITE_KAKAO_JS_KEY; // 카테고리 ID 상수 const CATEGORY_ID = { @@ -317,8 +317,15 @@ function XSection({ schedule }) { function KakaoMap({ lat, lng, name }) { const mapRef = useRef(null); const [mapLoaded, setMapLoaded] = useState(false); + const [mapError, setMapError] = useState(false); useEffect(() => { + // API 키가 없으면 에러 + if (!KAKAO_MAP_KEY) { + setMapError(true); + return; + } + // 카카오맵 SDK 동적 로드 if (!window.kakao?.maps) { const script = document.createElement('script'); @@ -326,6 +333,7 @@ function KakaoMap({ lat, lng, name }) { script.onload = () => { window.kakao.maps.load(() => setMapLoaded(true)); }; + script.onerror = () => setMapError(true); document.head.appendChild(script); } else { setMapLoaded(true); @@ -333,33 +341,55 @@ function KakaoMap({ lat, lng, name }) { }, []); useEffect(() => { - if (!mapLoaded || !mapRef.current) return; + if (!mapLoaded || !mapRef.current || mapError) return; - const position = new window.kakao.maps.LatLng(lat, lng); - const map = new window.kakao.maps.Map(mapRef.current, { - center: position, - level: 3, - }); - - // 마커 추가 - const marker = new window.kakao.maps.Marker({ - position, - map, - }); - - // 인포윈도우 추가 - if (name) { - const infowindow = new window.kakao.maps.InfoWindow({ - content: `
{name}
+클릭하여 길찾기
++ {formatSingleDate(schedule.date, schedule.time)} +
+일시
-{formatDateRange()}
- {schedule.time && ( -{formatTime(schedule.time)} 시작
+ {/* 장소 */} + {schedule.location_name && ( +{schedule.location_name}
+ {schedule.location_address && ( +{schedule.location_address}
+ )} ++ {decodeHtmlEntities(schedule.description)} +
+장소
-{schedule.location_name}
- {schedule.location_address && ( -{schedule.location_address}
- )} - {schedule.location_detail && ( -{schedule.location_detail}
- )} -- {decodeHtmlEntities(schedule.description)} -
-{schedule.location_name}
- {schedule.location_address && ( -{schedule.location_address}
- )} -{schedule.location_name}
+{schedule.location_name}
+ {schedule.location_address && ( +{schedule.location_address}
+ )} + {schedule.location_detail && ( +{schedule.location_detail}
+ )} +