|
5 | 5 | * |
6 | 6 | * 역할: |
7 | 7 | * - 미션 상세 정보 로드 |
8 | | - * - 지도에 미션 위치 표시 (카테고리별 색상) |
| 8 | + * - 지도에 미션 위치 표시 (상태별 색상) |
9 | 9 | * - 이미지 갤러리 렌더링 및 모달 |
10 | 10 | * - 햄버거 메뉴 토글 (작성자만) |
11 | 11 | * - 삭제 기능 |
|
15 | 15 |
|
16 | 16 | (function () { |
17 | 17 | let mapManager; |
18 | | - let missionStatus = null; |
| 18 | + let missionStatus = null; // ✨ 미션 상태 저장 |
19 | 19 |
|
20 | 20 | // URL에서 mission_id 추출 |
21 | 21 | const pathParts = window.location.pathname.split('/').filter(p => p !== ""); |
|
27 | 27 | // ==================== 지도 초기화 ==================== |
28 | 28 |
|
29 | 29 | /** |
30 | | - * 지도 초기화 (카테고리별 색상 마커) |
| 30 | + * 지도 초기화 (상태별 마커 색상) |
31 | 31 | */ |
32 | | - async function initMap(lat, lng, status, category) { |
| 32 | + async function initMap(lat, lng, status) { |
33 | 33 | const container = document.getElementById('map'); |
34 | 34 | if (!container) return; |
35 | 35 |
|
|
41 | 41 |
|
42 | 42 | await mapManager.init(); |
43 | 43 |
|
44 | | - // ✅ 카테고리별 색상 + 상태 클래스 적용 |
| 44 | + // ✨ 상태별 마커 생성 (InfoWindow 제거) |
45 | 45 | const marker = mapManager.addCustomMarker(lat, lng, { |
46 | | - category: category, // 카테고리별 색상 |
47 | | - status: status // WAITING/MATCHED/COMPLETED |
| 46 | + status: status // WAITING/MATCHED/COMPLETED |
48 | 47 | }); |
49 | 48 |
|
50 | 49 | mapManager.fitBoundsToLocations([{ lat, lng }]); |
51 | 50 | mapManager.setLevel(3); |
52 | 51 |
|
53 | | - console.log("✅ 지도 초기화 완료 (카테고리:", category, "상태:", status, ")"); |
| 52 | + console.log("✅ 지도 초기화 완료 (상태:", status, ")"); |
54 | 53 | } catch (err) { |
55 | 54 | console.error("지도 초기화 실패:", err); |
56 | 55 | } |
|
98 | 97 | } |
99 | 98 |
|
100 | 99 | const imagesHTML = images.map(img => { |
| 100 | + // 이미지 경로 처리 |
101 | 101 | let src = img.image; |
102 | 102 | if (src && !src.startsWith('http') && !src.startsWith('/')) { |
103 | 103 | src = '/' + src; |
|
144 | 144 |
|
145 | 145 | // ==================== 햄버거 메뉴 ==================== |
146 | 146 |
|
| 147 | + /** |
| 148 | + * 햄버거 메뉴 토글 |
| 149 | + */ |
147 | 150 | function toggleMenu() { |
148 | 151 | const menu = document.getElementById('dropdown-menu'); |
149 | 152 | const backdrop = document.getElementById('menu-backdrop'); |
150 | 153 |
|
151 | 154 | if (menu && backdrop) { |
152 | 155 | const isOpen = menu.classList.contains('show'); |
| 156 | + |
153 | 157 | if (isOpen) { |
154 | 158 | closeMenu(); |
155 | 159 | } else { |
|
159 | 163 | } |
160 | 164 | } |
161 | 165 |
|
| 166 | + /** |
| 167 | + * 메뉴 닫기 |
| 168 | + */ |
162 | 169 | function closeMenu() { |
163 | 170 | const menu = document.getElementById('dropdown-menu'); |
164 | 171 | const backdrop = document.getElementById('menu-backdrop'); |
|
167 | 174 | if (backdrop) backdrop.classList.remove('show'); |
168 | 175 | } |
169 | 176 |
|
| 177 | + /** |
| 178 | + * 햄버거 버튼 표시 (작성자만) |
| 179 | + */ |
170 | 180 | function showMenuButton(isAuthor) { |
171 | 181 | const menuButton = document.getElementById('menu-button'); |
| 182 | + |
172 | 183 | if (menuButton && isAuthor) { |
173 | 184 | menuButton.classList.add('visible'); |
174 | 185 | } |
|
177 | 188 | // ==================== 미션 삭제 ==================== |
178 | 189 |
|
179 | 190 | async function deleteMission() { |
| 191 | + // 메뉴 먼저 닫기 |
180 | 192 | closeMenu(); |
181 | 193 |
|
182 | 194 | if (!confirm('정말로 이 미션을 삭제하시겠습니까?\n삭제된 미션은 복구할 수 없습니다.')) { |
|
217 | 229 | return; |
218 | 230 | } |
219 | 231 |
|
| 232 | + // ✨ 미션 상태 저장 |
220 | 233 | missionStatus = mission.status; |
221 | 234 |
|
222 | 235 | // 1. 이미지 표시 |
223 | 236 | renderImages(mission.images); |
224 | 237 |
|
225 | | - // 2. 지도 표시 (좌표가 있을 때만) |
| 238 | + // 2. 지도 표시 (좌표가 있을 때만, 상태 포함) |
226 | 239 | if (mission.location_lat && mission.location_lng) { |
227 | | - // ✅ category 추가 전달 |
228 | | - initMap(mission.location_lat, mission.location_lng, mission.status, mission.category); |
| 240 | + initMap(mission.location_lat, mission.location_lng, mission.status); |
229 | 241 | } else { |
| 242 | + // ✨ 위치 정보가 없으면 "장소 설정 없음" 메시지 표시 |
230 | 243 | showNoLocationMessage(); |
231 | 244 | } |
232 | 245 |
|
|
240 | 253 |
|
241 | 254 | // ==================== 이벤트 핸들러 ==================== |
242 | 255 |
|
| 256 | + /** |
| 257 | + * 키보드 이벤트 (ESC로 모달/메뉴 닫기) |
| 258 | + */ |
243 | 259 | function initKeyboardEvents() { |
244 | 260 | document.addEventListener('keydown', function(e) { |
245 | 261 | if (e.key === 'Escape') { |
|
249 | 265 | }); |
250 | 266 | } |
251 | 267 |
|
| 268 | + /** |
| 269 | + * 모달 배경 클릭으로 닫기 |
| 270 | + */ |
252 | 271 | function initModalEvents() { |
253 | 272 | const modal = document.getElementById('imageModal'); |
254 | 273 | if (modal) { |
255 | 274 | modal.addEventListener('click', function(e) { |
256 | | - if (e.target === this) closeImageModal(); |
| 275 | + if (e.target === this) { |
| 276 | + closeImageModal(); |
| 277 | + } |
257 | 278 | }); |
258 | 279 | } |
259 | 280 | } |
260 | 281 |
|
| 282 | + /** |
| 283 | + * 햄버거 메뉴 이벤트 |
| 284 | + */ |
261 | 285 | function initMenuEvents() { |
262 | 286 | const menuButton = document.getElementById('menu-button'); |
263 | 287 | const backdrop = document.getElementById('menu-backdrop'); |
|
270 | 294 | }); |
271 | 295 | } |
272 | 296 |
|
| 297 | + // 삭제 버튼 이벤트 |
273 | 298 | if (deleteBtn) { |
274 | 299 | deleteBtn.addEventListener('click', function(e) { |
275 | 300 | e.preventDefault(); |
|
282 | 307 | backdrop.addEventListener('click', closeMenu); |
283 | 308 | } |
284 | 309 |
|
| 310 | + // 메뉴 외부 클릭 시 닫기 |
285 | 311 | document.addEventListener('click', function(e) { |
286 | 312 | const menu = document.getElementById('dropdown-menu'); |
287 | 313 | const menuButton = document.getElementById('menu-button'); |
288 | 314 |
|
289 | 315 | if (menu && menuButton) { |
290 | 316 | if (!menu.contains(e.target) && !menuButton.contains(e.target)) { |
291 | | - if (menu.classList.contains('show')) closeMenu(); |
| 317 | + if (menu.classList.contains('show')) { |
| 318 | + closeMenu(); |
| 319 | + } |
292 | 320 | } |
293 | 321 | } |
294 | 322 | }); |
|
297 | 325 | // ==================== 초기화 ==================== |
298 | 326 |
|
299 | 327 | function init() { |
| 328 | + // 전역 함수 노출 |
300 | 329 | window.deleteMission = deleteMission; |
301 | 330 | window.openImageModal = openImageModal; |
302 | 331 | window.closeImageModal = closeImageModal; |
303 | 332 |
|
| 333 | + // 이벤트 리스너 등록 |
304 | 334 | initKeyboardEvents(); |
305 | 335 | initModalEvents(); |
306 | 336 | initMenuEvents(); |
307 | 337 |
|
| 338 | + // 데이터 로드 |
308 | 339 | loadMissionDetail(); |
309 | 340 |
|
310 | 341 | console.log("✅ mission_detail.js 초기화 완료"); |
|
0 commit comments