/** * 봇 카드 컴포넌트 */ 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.type === 'meilisearch' ? ( <>
{bot.last_check_at ? new Date(bot.last_check_at).toLocaleString('ko-KR', { month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false, }) : '-'}
마지막 동기화
{bot.last_added_count?.toLocaleString() || '-'}
동기화 수
{bot.version || '-'}
버전
) : ( <>
{bot.schedules_added}
총 추가
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}
)} {/* 액션 버튼 */}
); }); export default BotCard;