import { useState, useEffect } from 'react'; import { useNavigate, Link } from 'react-router-dom'; import { motion } from 'framer-motion'; import { Disc3, Calendar, Users, Home, ChevronRight } from 'lucide-react'; import AdminLayout from '../../../components/admin/AdminLayout'; import * as authApi from '../../../api/admin/auth'; import { getMembers } from '../../../api/public/members'; import { getAlbums, getAlbum } from '../../../api/public/albums'; import { getSchedules } from '../../../api/public/schedules'; // 슬롯머신 스타일 롤링 숫자 컴포넌트 (아래에서 위로) function AnimatedNumber({ value }) { const digits = String(value).split(''); return ( {digits.map((digit, i) => ( {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(n => ( {n} ))} ))} ); } function AdminDashboard() { const navigate = useNavigate(); const [user, setUser] = useState(null); const [stats, setStats] = useState({ albums: 0, photos: 0, schedules: 0, members: 0 }); useEffect(() => { // 로그인 상태 확인 if (!authApi.hasToken()) { navigate('/admin'); return; } setUser(authApi.getCurrentUser()); // 토큰 유효성 검증 authApi.verifyToken() .catch(() => { authApi.logout(); navigate('/admin'); }); // 통계 데이터 가져오기 fetchStats(); }, [navigate]); const fetchStats = async () => { // 각 통계를 개별적으로 가져와서 하나가 실패해도 다른 것은 표시 try { const members = await getMembers(); setStats(prev => ({ ...prev, members: members.filter(m => !m.is_former).length })); } catch (e) { console.error('멤버 통계 오류:', e); } try { const albums = await getAlbums(); setStats(prev => ({ ...prev, albums: albums.length })); // 사진 수 계산 let totalPhotos = 0; for (const album of albums) { try { const detail = await getAlbum(album.id); if (detail.conceptPhotos) { Object.values(detail.conceptPhotos).forEach(photos => { totalPhotos += photos.length; }); } if (detail.teasers) { totalPhotos += detail.teasers.length; } } catch (e) { /* 개별 앨범 오류 무시 */ } } setStats(prev => ({ ...prev, photos: totalPhotos })); } catch (e) { console.error('앨범 통계 오류:', e); } try { const today = new Date(); const schedules = await getSchedules(today.getFullYear(), today.getMonth() + 1); setStats(prev => ({ ...prev, schedules: Array.isArray(schedules) ? schedules.length : 0 })); } catch (e) { console.error('일정 통계 오류:', e); } }; // 메뉴 아이템 const menuItems = [ { icon: Users, label: '멤버 관리', description: '멤버 정보 및 프로필 관리', path: '/admin/members', color: 'bg-primary' }, { icon: Disc3, label: '앨범 관리', description: '앨범, 트랙, 사진 업로드 및 관리', path: '/admin/albums', color: 'bg-purple-500' }, { icon: Calendar, label: '일정 관리', description: '일정 추가 및 관리', path: '/admin/schedule', color: 'bg-blue-500' }, ]; return ( {/* 메인 콘텐츠 */} {/* 브레드크럼 */} 관리자 대시보드 {/* 타이틀 */} 관리자 대시보드 fromis_9 팬사이트를 관리하세요 {/* 메뉴 그리드 */} {menuItems.map((item, index) => ( {item.label} {item.description} ))} {/* 빠른 통계 */} 빠른 통계 멤버 총 앨범 총 사진 총 일정 ); } export default AdminDashboard;
fromis_9 팬사이트를 관리하세요
{item.description}
멤버
총 앨범
총 사진
총 일정