'use client'; import { Card, Box, CardActionArea, CardContent, Typography, Avatar, Divider, IconButton, Menu, MenuItem, ListItemIcon } from '@mui/material'; import Link from 'next/link'; import { styles } from '@/styles/home'; import { useTheme, alpha } from '@mui/material/styles'; import DataObjectIcon from '@mui/icons-material/DataObject'; import DeleteIcon from '@mui/icons-material/Delete'; import FolderOpenIcon from '@mui/icons-material/FolderOpen'; import TokenIcon from '@mui/icons-material/Token'; import AssessmentIcon from '@mui/icons-material/Assessment'; import QuizIcon from '@mui/icons-material/Quiz'; import MoreVertIcon from '@mui/icons-material/MoreVert'; import { useTranslation } from 'react-i18next'; import { useState } from 'react'; /** * 统计项组件 */ const StatItem = ({ icon: Icon, count, label, color, isToken }) => { const theme = useTheme(); // 格式化数字 const displayCount = isToken ? (count || 0).toLocaleString() : count || 0; return ( {displayCount} {label} ); }; /** * 项目卡片组件 * @param {Object} props - 组件属性 * @param {Object} props.project - 项目数据 * @param {Function} props.onDeleteClick - 删除按钮点击事件处理函数 */ export default function ProjectCard({ project, onDeleteClick }) { const { t } = useTranslation(); const theme = useTheme(); const [processingId, setProcessingId] = useState(false); // 菜单状态 const [anchorEl, setAnchorEl] = useState(null); const open = Boolean(anchorEl); // 打开项目目录 const handleOpenDirectory = async event => { event.stopPropagation(); event.preventDefault(); if (processingId) return; try { setProcessingId(true); const response = await fetch('/api/projects/open-directory', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ projectId: project.id }) }); if (!response.ok) { const data = await response.json(); throw new Error(data.error || t('migration.openDirectoryFailed')); } // 成功打开目录,不需要特别处理 } catch (error) { console.error('打开目录错误:', error); alert(error.message); } finally { setProcessingId(false); } }; // 处理菜单打开 const handleMenuClick = event => { event.stopPropagation(); event.preventDefault(); setAnchorEl(event.currentTarget); }; // 处理菜单关闭 const handleMenuClose = event => { if (event) { event.stopPropagation(); event.preventDefault(); } setAnchorEl(null); }; // 处理打开目录点击 const handleOpenDirectoryClick = event => { handleMenuClose(event); handleOpenDirectory(event); }; // 处理删除点击 const handleDeleteClick = event => { handleMenuClose(event); onDeleteClick(event, project); }; return ( {/* 头部:Avatar + Title + Menu */} {project.name.charAt(0).toUpperCase()} {project.name} ID: {project.id} {/* 描述 */} {project.description || t('projects.noDescription', { defaultValue: '暂无描述' })} {/* 统计数据 */} {/* 操作菜单 */} { e.preventDefault(); e.stopPropagation(); }} transformOrigin={{ horizontal: 'right', vertical: 'top' }} anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }} PaperProps={{ elevation: 3, sx: { borderRadius: '12px', minWidth: 160, mt: 0.5 } }} > {t('projects.openDirectory')} {t('common.delete')} ); }