feat(dc): Complete Phase 1 - Portal workbench page development
Summary: - Implement DC module Portal page with 3 tool cards - Create ToolCard component with decorative background and hover animations - Implement TaskList component with table layout and progress bars - Implement AssetLibrary component with tab switching and file cards - Complete database verification (4 tables confirmed) - Complete backend API verification (6 endpoints ready) - Optimize UI to match prototype design (V2.html) Frontend Components (~715 lines): - components/ToolCard.tsx - Tool cards with animations - components/TaskList.tsx - Recent tasks table view - components/AssetLibrary.tsx - Data asset library with tabs - hooks/useRecentTasks.ts - Task state management - hooks/useAssets.ts - Asset state management - pages/Portal.tsx - Main portal page - types/portal.ts - TypeScript type definitions Backend Verification: - Backend API: 1495 lines code verified - Database: dc_schema with 4 tables verified - API endpoints: 6 endpoints tested (templates API works) Documentation: - Database verification report - Backend API test report - Phase 1 completion summary - UI optimization report - Development task checklist - Development plan for Tool B Status: Phase 1 completed (100%), ready for browser testing Next: Phase 2 - Tool B Step 1 and 2 development
This commit is contained in:
123
frontend-v2/src/modules/dc/components/ToolCard.tsx
Normal file
123
frontend-v2/src/modules/dc/components/ToolCard.tsx
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* DC模块 - 工具卡片组件
|
||||
*
|
||||
* 用于Portal页面的3个工具快速启动卡片
|
||||
* 设计参考:智能数据清洗工作台V2.html
|
||||
*/
|
||||
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import {
|
||||
FileSpreadsheet,
|
||||
Bot,
|
||||
Table2,
|
||||
ArrowRight,
|
||||
LucideIcon
|
||||
} from 'lucide-react';
|
||||
import type { ToolCard as ToolCardType } from '../types/portal';
|
||||
|
||||
interface ToolCardProps {
|
||||
tool: ToolCardType;
|
||||
}
|
||||
|
||||
const iconMap: Record<string, LucideIcon> = {
|
||||
FileSpreadsheet,
|
||||
Bot,
|
||||
Table2
|
||||
};
|
||||
|
||||
const colorMap = {
|
||||
blue: {
|
||||
bg: 'bg-blue-100',
|
||||
icon: 'text-blue-600',
|
||||
decorBg: 'bg-blue-50',
|
||||
hoverText: 'group-hover:text-blue-600',
|
||||
actionText: 'text-blue-600'
|
||||
},
|
||||
purple: {
|
||||
bg: 'bg-purple-100',
|
||||
icon: 'text-purple-600',
|
||||
decorBg: 'bg-purple-50',
|
||||
hoverText: 'group-hover:text-purple-600',
|
||||
actionText: 'text-purple-600'
|
||||
},
|
||||
emerald: {
|
||||
bg: 'bg-emerald-100',
|
||||
icon: 'text-emerald-600',
|
||||
decorBg: 'bg-emerald-50',
|
||||
hoverText: 'group-hover:text-emerald-600',
|
||||
actionText: 'text-emerald-600'
|
||||
}
|
||||
};
|
||||
|
||||
const ToolCard = ({ tool }: ToolCardProps) => {
|
||||
const navigate = useNavigate();
|
||||
const Icon = iconMap[tool.icon] || Bot;
|
||||
const colors = colorMap[tool.color];
|
||||
|
||||
const isDisabled = tool.status === 'disabled';
|
||||
|
||||
const handleClick = () => {
|
||||
if (!isDisabled) {
|
||||
navigate(tool.route);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
onClick={handleClick}
|
||||
className={`
|
||||
bg-white rounded-xl shadow-sm border border-slate-200 p-6
|
||||
transition-shadow group relative overflow-hidden
|
||||
${isDisabled ? 'opacity-60 cursor-not-allowed' : 'hover:shadow-md cursor-pointer'}
|
||||
`}
|
||||
>
|
||||
{/* 装饰性圆形背景 */}
|
||||
<div className={`
|
||||
absolute top-0 right-0 w-24 h-24 rounded-bl-full -mr-4 -mt-4
|
||||
transition-transform
|
||||
${colors.decorBg}
|
||||
${!isDisabled && 'group-hover:scale-110'}
|
||||
`} />
|
||||
|
||||
<div className="relative">
|
||||
{/* 图标 */}
|
||||
<div className={`
|
||||
w-12 h-12 ${colors.bg} rounded-lg
|
||||
flex items-center justify-center mb-4
|
||||
${colors.icon}
|
||||
`}>
|
||||
<Icon className="w-7 h-7" />
|
||||
</div>
|
||||
|
||||
{/* 标题 */}
|
||||
<h3 className={`
|
||||
text-lg font-bold text-slate-900 mb-2
|
||||
transition-colors
|
||||
${!isDisabled && colors.hoverText}
|
||||
`}>
|
||||
{tool.title}
|
||||
</h3>
|
||||
|
||||
{/* 描述 - 固定高度确保对齐 */}
|
||||
<p className="text-sm text-slate-500 mb-4 h-10 leading-relaxed">
|
||||
{tool.description}
|
||||
</p>
|
||||
|
||||
{/* 行动按钮 */}
|
||||
{isDisabled ? (
|
||||
<div className="flex items-center text-sm font-medium text-slate-400">
|
||||
<span>敬请期待</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className={`flex items-center text-sm font-medium ${colors.actionText}`}>
|
||||
<span>{tool.id === 'tool-a' ? '开始合并' : tool.id === 'tool-b' ? '新建提取任务' : '打开编辑器'}</span>
|
||||
<ArrowRight className="w-4 h-4 ml-1 transition-transform group-hover:translate-x-1" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ToolCard;
|
||||
|
||||
Reference in New Issue
Block a user