refactor: 봇 관리 UI 통일 및 개선
- 모든 섹션에 테이블형 디자인 통일 - 섹션 헤더에서 "N개의 봇" 텍스트 제거 - Meilisearch 섹션에 전용 아이콘 적용 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
b5118f2dea
commit
e729d33aee
1 changed files with 9 additions and 55 deletions
|
|
@ -2,9 +2,9 @@ import { useState, useEffect, useMemo } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
import { motion, AnimatePresence } from 'framer-motion';
|
import { motion, AnimatePresence } from 'framer-motion';
|
||||||
import { Home, ChevronRight, Bot, CheckCircle, XCircle, RefreshCw, Plus, Database, Youtube } from 'lucide-react';
|
import { Home, ChevronRight, Bot, CheckCircle, XCircle, RefreshCw, Plus, Youtube } from 'lucide-react';
|
||||||
import { Toast, Tooltip, AnimatedNumber } from '@/components/common';
|
import { Toast, Tooltip, AnimatedNumber } from '@/components/common';
|
||||||
import { AdminLayout, BotCard, XIcon, BotListItem, BotMiniCard, BotTableRow, BotTable } from '@/components/pc/admin';
|
import { AdminLayout, XIcon, MeilisearchIcon, BotTableRow, BotTable } from '@/components/pc/admin';
|
||||||
import { useAdminAuth } from '@/hooks/pc/admin';
|
import { useAdminAuth } from '@/hooks/pc/admin';
|
||||||
import { useToast } from '@/hooks/common';
|
import { useToast } from '@/hooks/common';
|
||||||
import * as botsApi from '@/api/admin/bots';
|
import * as botsApi from '@/api/admin/bots';
|
||||||
|
|
@ -13,10 +13,10 @@ import * as botsApi from '@/api/admin/bots';
|
||||||
const SECTIONS = {
|
const SECTIONS = {
|
||||||
meilisearch: {
|
meilisearch: {
|
||||||
title: 'Meilisearch',
|
title: 'Meilisearch',
|
||||||
icon: Database,
|
icon: MeilisearchIcon,
|
||||||
color: 'text-purple-500',
|
color: 'text-pink-500',
|
||||||
bgColor: 'bg-purple-50',
|
bgColor: 'bg-pink-50',
|
||||||
borderColor: 'border-purple-100',
|
borderColor: 'border-pink-100',
|
||||||
},
|
},
|
||||||
youtube: {
|
youtube: {
|
||||||
title: 'YouTube',
|
title: 'YouTube',
|
||||||
|
|
@ -349,10 +349,7 @@ function ScheduleBots() {
|
||||||
<div className={`w-8 h-8 rounded-lg ${section.bgColor} flex items-center justify-center`}>
|
<div className={`w-8 h-8 rounded-lg ${section.bgColor} flex items-center justify-center`}>
|
||||||
<SectionIcon size={18} className={section.color} />
|
<SectionIcon size={18} className={section.color} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<h2 className="font-bold text-gray-900">{section.title}</h2>
|
||||||
<h2 className="font-bold text-gray-900">{section.title}</h2>
|
|
||||||
<p className="text-xs text-gray-500">{sectionBots.length}개의 봇</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
{section.canAdd && (
|
{section.canAdd && (
|
||||||
|
|
@ -379,7 +376,7 @@ function ScheduleBots() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 봇 목록 - 타입별 다른 스타일 */}
|
{/* 봇 목록 - 테이블형 */}
|
||||||
{sectionBots.length === 0 ? (
|
{sectionBots.length === 0 ? (
|
||||||
<div className="text-center py-12 text-gray-400">
|
<div className="text-center py-12 text-gray-400">
|
||||||
<Bot size={36} className="mx-auto mb-3 opacity-30" />
|
<Bot size={36} className="mx-auto mb-3 opacity-30" />
|
||||||
|
|
@ -388,29 +385,7 @@ function ScheduleBots() {
|
||||||
<p className="text-xs mt-1">위의 버튼을 클릭하여 봇을 추가하세요</p>
|
<p className="text-xs mt-1">위의 버튼을 클릭하여 봇을 추가하세요</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : type === 'meilisearch' ? (
|
) : (
|
||||||
/* Meilisearch: 리스트형 */
|
|
||||||
<div className="p-4 space-y-2">
|
|
||||||
{sectionBots.map((bot, index) => (
|
|
||||||
<BotListItem
|
|
||||||
key={bot.id}
|
|
||||||
bot={bot}
|
|
||||||
index={index}
|
|
||||||
isInitialLoad={isInitialLoad}
|
|
||||||
syncing={syncing}
|
|
||||||
statusInfo={getStatusInfo(bot.status)}
|
|
||||||
onSync={handleSyncAllVideos}
|
|
||||||
onToggle={toggleBot}
|
|
||||||
onAnimationComplete={() =>
|
|
||||||
isInitialLoad && index === sectionBots.length - 1 && setIsInitialLoad(false)
|
|
||||||
}
|
|
||||||
formatTime={formatTime}
|
|
||||||
formatInterval={formatInterval}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
) : type === 'x' ? (
|
|
||||||
/* X: 테이블형 */
|
|
||||||
<BotTable>
|
<BotTable>
|
||||||
{sectionBots.map((bot, index) => (
|
{sectionBots.map((bot, index) => (
|
||||||
<BotTableRow
|
<BotTableRow
|
||||||
|
|
@ -430,27 +405,6 @@ function ScheduleBots() {
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</BotTable>
|
</BotTable>
|
||||||
) : (
|
|
||||||
/* YouTube: 미니 카드형 */
|
|
||||||
<div className="p-6 grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-4">
|
|
||||||
{sectionBots.map((bot, index) => (
|
|
||||||
<BotMiniCard
|
|
||||||
key={bot.id}
|
|
||||||
bot={bot}
|
|
||||||
index={index}
|
|
||||||
isInitialLoad={isInitialLoad}
|
|
||||||
syncing={syncing}
|
|
||||||
statusInfo={getStatusInfo(bot.status)}
|
|
||||||
onSync={handleSyncAllVideos}
|
|
||||||
onToggle={toggleBot}
|
|
||||||
onAnimationComplete={() =>
|
|
||||||
isInitialLoad && index === sectionBots.length - 1 && setIsInitialLoad(false)
|
|
||||||
}
|
|
||||||
formatTime={formatTime}
|
|
||||||
formatInterval={formatInterval}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</motion.div>
|
</motion.div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue