봇 관리
일정 자동화 봇을 관리합니다
봇 목록
등록된 봇이 없습니다
위의 버튼을 클릭하여 봇을 추가하세요
{bot.name}
{statusInfo.text} YouTube채널: {bot.channel_name || bot.channel_id} | {bot.include_shorts ? ' Shorts 포함' : ' Shorts 제외'} | {bot.check_interval}분 간격
{/* 메타 정보 */}import { useState, useEffect } from 'react';
import { useNavigate, Link } from 'react-router-dom';
import { motion, AnimatePresence } from 'framer-motion';
import {
LogOut, Home, ChevronRight, Bot, Play, Square,
Youtube, Calendar, Clock, CheckCircle, XCircle, RefreshCw, Download
} from 'lucide-react';
import Toast from '../../../components/Toast';
function AdminScheduleBots() {
const navigate = useNavigate();
const [user, setUser] = useState(null);
const [toast, setToast] = useState(null);
const [bots, setBots] = useState([]);
const [loading, setLoading] = useState(true);
const [syncing, setSyncing] = useState(null); // 동기화 중인 봇 ID
// Toast 자동 숨김
useEffect(() => {
if (toast) {
const timer = setTimeout(() => setToast(null), 3000);
return () => clearTimeout(timer);
}
}, [toast]);
useEffect(() => {
const token = localStorage.getItem('adminToken');
const userData = localStorage.getItem('adminUser');
if (!token || !userData) {
navigate('/admin');
return;
}
setUser(JSON.parse(userData));
fetchBots();
}, [navigate]);
// 봇 목록 조회
const fetchBots = async () => {
try {
const token = localStorage.getItem('adminToken');
const response = await fetch('/api/admin/bots', {
headers: { Authorization: `Bearer ${token}` }
});
if (response.ok) {
const data = await response.json();
setBots(data);
}
} catch (error) {
console.error('봇 목록 조회 오류:', error);
setToast({ type: 'error', message: '봇 목록을 불러올 수 없습니다.' });
} finally {
setLoading(false);
}
};
const handleLogout = () => {
localStorage.removeItem('adminToken');
localStorage.removeItem('adminUser');
navigate('/admin');
};
// 봇 시작/정지 토글
const toggleBot = async (botId, currentStatus) => {
try {
const token = localStorage.getItem('adminToken');
const action = currentStatus === 'running' ? 'stop' : 'start';
const response = await fetch(`/api/admin/bots/${botId}/${action}`, {
method: 'POST',
headers: { Authorization: `Bearer ${token}` }
});
if (response.ok) {
setToast({
type: 'success',
message: action === 'start' ? '봇이 시작되었습니다.' : '봇이 정지되었습니다.'
});
fetchBots(); // 목록 새로고침
} else {
const data = await response.json();
setToast({ type: 'error', message: data.error || '작업 실패' });
}
} catch (error) {
console.error('봇 토글 오류:', error);
setToast({ type: 'error', message: '작업 중 오류가 발생했습니다.' });
}
};
// 전체 동기화
const syncAllVideos = async (botId) => {
setSyncing(botId);
try {
const token = localStorage.getItem('adminToken');
const response = await fetch(`/api/admin/bots/${botId}/sync-all`, {
method: 'POST',
headers: { Authorization: `Bearer ${token}` }
});
if (response.ok) {
const data = await response.json();
setToast({
type: 'success',
message: `${data.addedCount}개 일정이 추가되었습니다. (전체 ${data.total}개)`
});
fetchBots();
} else {
const data = await response.json();
setToast({ type: 'error', message: data.error || '동기화 실패' });
}
} catch (error) {
console.error('전체 동기화 오류:', error);
setToast({ type: 'error', message: '동기화 중 오류가 발생했습니다.' });
} finally {
setSyncing(null);
}
};
// 상태 아이콘 및 색상
const getStatusInfo = (status) => {
switch (status) {
case 'running':
return {
icon:
일정 자동화 봇을 관리합니다
등록된 봇이 없습니다
위의 버튼을 클릭하여 봇을 추가하세요
채널: {bot.channel_name || bot.channel_id} | {bot.include_shorts ? ' Shorts 포함' : ' Shorts 제외'} | {bot.check_interval}분 간격
{/* 메타 정보 */}