Files
software-workspace/src/components/ProjectCard.tsx
T
shenjianZ b6f15f82d8 feat: 新增 QuantaNote 项目展示,重构项目卡片与截图浏览组件
- 新增 QuantaNote 完整项目数据(特性描述、截图、Logo)
  - 为所有项目添加 logo 和 websiteUrl 字段支持
  - 移除 stars/forks 相关展示与排序逻辑
  - ScreenshotCarousel 增加左右切换箭头和 Lightbox 全屏预览(支持键盘导航)
  - 更新项目创建文档,补充 logo 和 installGuide 配置说明
2026-05-22 16:07:30 +08:00

85 lines
2.7 KiB
TypeScript

import { Link } from 'react-router-dom';
import { ExternalLink, Download, BookOpen, Globe } from 'lucide-react';
import { useI18n } from '../hooks/useI18n';
import { siteData } from '../data/siteData';
import { getIcon } from '../utils/iconRegistry';
import type { Project } from '../types';
interface ProjectCardProps {
project: Project;
}
export default function ProjectCard({ project }: ProjectCardProps) {
const { t, bi, lang } = useI18n();
const status = siteData.statuses[project.status];
const IconComponent = getIcon(project.icon);
return (
<div className="project-card">
<div className="project-card-header">
<div className="project-icon">
{project.logo
? <img src={project.logo} alt={project.name} className="project-logo" />
: (IconComponent && <IconComponent size={22} />)
}
</div>
<div className="project-card-info">
<div className="project-name">
<Link to={`/projects/${project.id}`}>{project.displayName[lang] || project.name}</Link>
{status && (
<span className="badge badge-status" style={{ '--status-color': status.color } as React.CSSProperties}>
{bi(status.label)}
</span>
)}
</div>
<div className="project-slogan">{bi(project.slogan)}</div>
</div>
</div>
<div className="project-card-meta">
{project.techStack.slice(0, 4).map((tech) => (
<span key={tech} className="badge">
{tech}
</span>
))}
{project.platforms.slice(0, 3).map((platform) => (
<span key={platform} className="badge">
{siteData.platforms[platform] || platform}
</span>
))}
</div>
<div className="project-card-actions">
<a href={project.repoUrl} target="_blank" rel="noopener noreferrer" className="btn btn-sm">
<ExternalLink size={14} /> GitHub
</a>
{project.downloads.length > 0 && (
<Link to={`/projects/${project.id}`} className="btn btn-sm">
<Download size={14} /> {t('common.download')}
</Link>
)}
{project.websiteUrl && (
<a
href={project.websiteUrl}
target="_blank"
rel="noopener noreferrer"
className="btn btn-sm"
>
<Globe size={14} /> {t('detail.website')}
</a>
)}
{project.docsUrl && (
<a
href={project.docsUrl}
target="_blank"
rel="noopener noreferrer"
className="btn btn-sm"
>
<BookOpen size={14} /> {t('common.docs')}
</a>
)}
</div>
</div>
);
}