import React, { useState, useRef, useEffect } from 'react'; import { NavLink, useLocation, Link, useNavigate } from 'react-router-dom'; import { Home, Globe, Users, Menu, X, Gamepad2, Map, Shield, LogIn, LogOut, User, Settings, BarChart2 } from 'lucide-react'; import { motion, AnimatePresence } from 'framer-motion'; import { useAuth } from '../contexts/AuthContext'; import { io } from 'socket.io-client'; // 사이드바 네비게이션 컴포넌트 const Sidebar = ({ isMobile = false }) => { const [isOpen, setIsOpen] = useState(false); const [showProfileMenu, setShowProfileMenu] = useState(false); const [showLogoutDialog, setShowLogoutDialog] = useState(false); const [minecraftLink, setMinecraftLink] = useState(null); const [serverOnline, setServerOnline] = useState(false); const [toast, setToast] = useState(null); const location = useLocation(); const navigate = useNavigate(); const { isLoggedIn, isAdmin, user, logout } = useAuth(); const profileMenuRef = useRef(null); const menuItems = [ { path: '/', icon: Home, label: '홈' }, { path: '/players', icon: Users, label: '플레이어', matchPaths: ['/players', '/player/'] }, { path: '/worlds', icon: Globe, label: '월드 정보' }, { path: '/worldmap', icon: Map, label: '월드맵' }, ]; // 커스텀 활성 상태 확인 함수 const isMenuActive = (item) => { if (item.matchPaths) { return item.matchPaths.some(path => location.pathname.startsWith(path)); } return location.pathname === item.path; }; // 프로필 메뉴 외부 클릭 시 닫기 useEffect(() => { const handleClickOutside = (e) => { if (profileMenuRef.current && !profileMenuRef.current.contains(e.target)) { setShowProfileMenu(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); // 연동 상태 확인 useEffect(() => { if (!isLoggedIn) { setMinecraftLink(null); return; } const fetchLinkStatus = async () => { try { const token = localStorage.getItem('token'); const res = await fetch('/link/status', { headers: { 'Authorization': `Bearer ${token}` } }); const data = await res.json(); if (data.linked) { setMinecraftLink(data); } } catch (error) { console.error('연동 상태 확인 실패:', error); } }; fetchLinkStatus(); }, [isLoggedIn, user]); // 서버 상태 확인 (socket.io) useEffect(() => { const socket = io(window.location.origin, { path: '/socket.io' }); socket.on('status', (status) => { setServerOnline(status?.online || false); }); return () => socket.disconnect(); }, []); // 토스트 자동 숨기기 useEffect(() => { if (toast) { const timer = setTimeout(() => setToast(null), 3000); return () => clearTimeout(timer); } }, [toast]); // 통계 페이지 이동 핸들러 const handleStatsClick = () => { if (!serverOnline) { setToast('서버가 오프라인입니다.'); setShowProfileMenu(false); return; } setShowProfileMenu(false); navigate(`/player/${minecraftLink.minecraftUuid}/stats`); }; // 로그아웃 핸들러 const handleLogout = () => { setShowProfileMenu(false); setShowLogoutDialog(true); }; const confirmLogout = () => { logout(); setShowLogoutDialog(false); navigate('/'); }; // 프로필 메뉴 컴포넌트 const ProfileMenu = () => ( {showProfileMenu && ( {/* 프로필 정보 */}
프로필 { e.target.src = 'https://via.placeholder.com/48'; }} />

{user?.name}

{isAdmin && ( 관리자 )}

{user?.email}

{/* 메뉴 항목 */}
{minecraftLink && ( )} {isAdmin && ( )}
)} ); // 로그아웃 확인 다이얼로그 const LogoutDialog = () => ( {showLogoutDialog && ( <> {/* 오버레이 */} setShowLogoutDialog(false)} /> {/* 다이얼로그 */}

로그아웃

정말 로그아웃 하시겠습니까?

)}
); // 프로필 영역 (클릭 가능) const ProfileSection = () => (
); // 모바일: 상단 툴바 + 햄버거 메뉴 사이드바 if (isMobile) { return ( <> {/* 토스트 알림 */} {toast && ( {toast} )} {/* 상단 툴바 */}
{/* 햄버거 메뉴 버튼 */} {/* 로고/타이틀 */}
마인크래프트
{/* 로그인/유저 */} {isLoggedIn ? (
{/* 드롭다운 메뉴 */} {showProfileMenu && ( {/* 프로필 정보 */}
프로필 { e.target.src = 'https://via.placeholder.com/40'; }} />

{user?.name}

{user?.email}

{/* 메뉴 항목 */}
{minecraftLink && ( )} {isAdmin && ( )}
)}
) : ( )}
{/* 상단 툴바 높이만큼 공간 확보 */}
{/* 오버레이 */} {isOpen && ( setIsOpen(false)} /> )} {/* 사이드바 (슬라이드) */} {isOpen && ( {/* 사이드바 헤더 */}

마인크래프트

서버 대시보드

{/* 메뉴 */} {/* 하단: 로그인 버튼 (비로그인 시에만) */} {!isLoggedIn && (
setIsOpen(false)} className="flex items-center justify-center gap-2 w-full px-4 py-3 bg-mc-green hover:bg-mc-green/80 text-white font-medium rounded-xl transition-colors" > 로그인
)}
)}
); } // PC: 기존 사이드바 return ( <> {/* 토스트 알림 */} {toast && ( {toast} )} {/* 데스크탑 사이드바 (항상 표시) */} {/* 데스크톱용 사이드바 spacer */}
); }; export default Sidebar;