/** * 봇 카드 컴포넌트 */ import { memo } from 'react'; import { motion } from 'framer-motion'; import { Youtube, Play, Square, RefreshCw, Download } from 'lucide-react'; // X 아이콘 컴포넌트 export const XIcon = ({ size = 20, fill = 'currentColor' }) => ( ); // Meilisearch 아이콘 컴포넌트 export const MeilisearchIcon = ({ size = 20 }) => ( ); /** * @param {Object} props * @param {Object} props.bot - 봇 데이터 * @param {number} props.index - 인덱스 (애니메이션용) * @param {boolean} props.isInitialLoad - 첫 로드 여부 * @param {string|null} props.syncing - 동기화 중인 봇 ID * @param {Object} props.statusInfo - 상태 정보 (text, color, bg, dot) * @param {Function} props.onSync - 동기화 핸들러 * @param {Function} props.onToggle - 토글 핸들러 * @param {Function} props.onAnimationComplete - 애니메이션 완료 핸들러 * @param {Function} props.formatTime - 시간 포맷 함수 * @param {Function} props.formatInterval - 간격 포맷 함수 */ const BotCard = memo(function BotCard({ bot, index, isInitialLoad, syncing, statusInfo, onSync, onToggle, onAnimationComplete, formatTime, formatInterval, }) { return ( {/* 상단 헤더 */} {bot.type === 'x' ? ( ) : bot.type === 'meilisearch' ? ( ) : ( )} {bot.name} {bot.last_check_at ? `${formatTime(bot.last_check_at)}에 업데이트됨` : '아직 업데이트 없음'} {statusInfo.text} {/* 통계 정보 */} {bot.schedules_added || 0} 총 추가 0 ? 'text-green-500' : 'text-gray-400'}`} > +{bot.last_added_count || 0} 마지막 {formatInterval(bot.check_interval)} 업데이트 간격 {/* 오류 메시지 */} {bot.status === 'error' && bot.error_message && ( {bot.error_message} )} {/* 액션 버튼 */} onSync(bot.id)} disabled={syncing === bot.id} className="flex-1 flex items-center justify-center gap-2 px-4 py-2.5 bg-blue-500 text-white rounded-lg font-medium transition-colors hover:bg-blue-600 disabled:opacity-50" > {syncing === bot.id ? ( <> 동기화 중... > ) : ( <> 전체 동기화 > )} onToggle(bot.id, bot.status, bot.name)} className={`flex items-center justify-center gap-2 px-4 py-2.5 rounded-lg font-medium transition-colors ${ bot.status === 'running' ? 'bg-gray-100 text-gray-600 hover:bg-gray-200' : 'bg-green-500 text-white hover:bg-green-600' }`} > {bot.status === 'running' ? ( <> 정지 > ) : ( <> 시작 > )} ); }); export default BotCard;
{bot.last_check_at ? `${formatTime(bot.last_check_at)}에 업데이트됨` : '아직 업데이트 없음'}