Files
mixvideo-v2/apps/desktop/src/components/Navigation.tsx
imeepos 7d8b8a3de1 feat: 实现AI画布工具并隐藏,设置项目为首页
- 新增完整的AI画布工具系统
  - 可视化节点编辑器,支持拖拽连线
  - 多种节点类型:文本输入、图片生成、视频生成等
  - 智能连接验证和数据流转换
  - 异步处理引擎,支持进度追踪和取消
  - 批量处理系统,支持并发处理
  - AI服务集成框架,支持多种AI API

- 用户体验优化
  - 智能弹框定位,防止被遮挡
  - 节点删除功能(悬停删除按钮 + 键盘快捷键)
  - 通知系统和错误处理
  - 快速开始模板
  - 键盘快捷键支持

- 界面调整
  - 暂时隐藏AI画布,保留代码
  - 设置项目列表为首页
  - 简化导航栏结构
2025-08-07 10:12:46 +08:00

140 lines
4.4 KiB
TypeScript

import React from 'react';
import { Link, useLocation } from 'react-router-dom';
import {
FolderIcon,
UserGroupIcon,
CpuChipIcon,
DocumentDuplicateIcon,
WrenchScrewdriverIcon,
SparklesIcon,
CommandLineIcon,
PaintBrushIcon,
} from '@heroicons/react/24/outline';
const Navigation: React.FC = () => {
const location = useLocation();
const navItems = [
{
name: '项目',
href: '/',
icon: FolderIcon,
description: '管理项目和素材'
},
// AI画布暂时隐藏
// {
// name: 'AI画布',
// href: '/canvas-tool',
// icon: PaintBrushIcon,
// description: '可视化AI内容生成画布'
// },
{
name: '模特',
href: '/models',
icon: UserGroupIcon,
description: '管理模特信息'
},
{
name: '模板',
href: '/templates',
icon: DocumentDuplicateIcon,
description: '管理剪映模板'
},
{
name: '分类',
href: '/ai-classification-settings',
icon: CpuChipIcon,
description: '管理AI视频分类规则'
},
{
name: '穿搭',
href: '/outfit',
icon: SparklesIcon,
description: 'AI穿搭方案推荐与素材检索'
},
{
name: 'ComfyUI',
href: '/comfyui',
icon: CommandLineIcon,
description: 'ComfyUI工作流管理与执行'
},
{
name: '工具',
href: '/tools',
icon: WrenchScrewdriverIcon,
description: 'AI检索图片/数据清洗工具'
}
];
const isActive = (href: string) => {
if (href === '/') {
return location.pathname === '/';
}
// 特殊处理:工具页面只匹配 /tools 本身,不匹配子路径
if (href === '/tools') {
return location.pathname === '/tools';
}
// 特殊处理:项目页面匹配 /projects 和 /project/:id
if (href === '/projects') {
return location.pathname === '/projects' || location.pathname.startsWith('/project/');
}
// 其他路径使用 startsWith 匹配
return location.pathname.startsWith(href);
};
return (
<nav className="bg-white/95 backdrop-blur-sm shadow-sm border-b border-gray-200/50 sticky top-0 z-50 flex-shrink-0">
<div className="px-4 sm:px-2 lg:px-4">
<div className="flex items-center justify-between h-16">
{/* 增强的 Logo */}
<div className="flex items-center">
<div className="flex-shrink-0">
<div className="flex items-center gap-2">
<div className="w-8 h-8 bg-gradient-to-br from-primary-500 to-primary-600 rounded-lg flex items-center justify-center shadow-sm">
<span className="text-white font-bold text-sm">M</span>
</div>
<h1 className="text-xl font-bold bg-gradient-to-r from-gray-900 to-gray-700 bg-clip-text text-transparent">MixVideo</h1>
</div>
</div>
</div>
<div>
<div className="ml-4 flex items-baseline space-x-2">
{navItems.map((item) => {
const Icon = item.icon;
const active = isActive(item.href);
return (
<Link
key={item.name}
to={item.href}
className={`group flex items-center px-2 py-2 rounded-lg text-sm font-medium transition-all duration-200 relative overflow-hidden ${
active
? 'bg-gradient-to-r from-primary-100 to-primary-200 text-primary-700 shadow-sm'
: 'text-gray-600 hover:text-gray-900 hover:bg-gradient-to-r hover:from-gray-50 hover:to-gray-100'
}`}
title={item.description}
>
{active && (
<div className="absolute inset-0 bg-gradient-to-r from-primary-500/10 to-primary-600/10"></div>
)}
<Icon className={`mr-2 h-5 w-5 relative z-10 transition-all duration-200 ${
active ? 'text-primary-600' : 'text-gray-400 group-hover:text-gray-600 group-hover:scale-110'
}`} />
<span className="relative z-10">{item.name}</span>
</Link>
);
})}
</div>
</div>
</div>
</div>
</nav>
);
};
export default Navigation;