Files
2025-11-28 14:46:17 +08:00

83 lines
3.4 KiB
TypeScript

import React from 'react';
import { ProjectItem, Language } from '../types';
import { ExternalLink, Code, Gamepad2, Car, BarChart3 } from 'lucide-react';
interface Props {
project: ProjectItem;
lang: Language;
}
const ProjectCard: React.FC<Props> = ({ project, lang }) => {
// Select a placeholder icon fallback
const getIcon = () => {
switch (project.imageType) {
case 'car': return <Car size={32} className="text-white opacity-80" />;
case 'game': return <Gamepad2 size={32} className="text-white opacity-80" />;
case 'chart': return <BarChart3 size={32} className="text-white opacity-80" />;
default: return <Code size={32} className="text-white opacity-80" />;
}
};
return (
<div className="group bg-white rounded-2xl overflow-hidden shadow-md hover:shadow-2xl transition-all duration-300 border border-slate-100 flex flex-col h-full transform hover:-translate-y-1">
{/* Image Area - Increased height for "Rich" feel */}
<div className="relative h-64 w-full overflow-hidden bg-slate-900">
{project.imageUrl ? (
<img
src={project.imageUrl}
alt={project.title[lang]}
className="w-full h-full object-cover transform group-hover:scale-110 transition-transform duration-700 ease-out"
loading="lazy"
/>
) : (
<div className="w-full h-full flex items-center justify-center bg-gradient-to-br from-slate-800 to-indigo-900">
{getIcon()}
</div>
)}
{/* Dark Gradient Overlay for text readability at bottom */}
<div className="absolute inset-0 bg-gradient-to-t from-slate-900/80 via-transparent to-transparent opacity-60"></div>
{/* Type badge */}
<div className="absolute top-4 right-4 bg-white/10 backdrop-blur-md px-3 py-1 rounded-full border border-white/20 shadow-sm">
<span className="text-xs font-bold text-white tracking-wide uppercase">
{project.imageType || 'Dev'}
</span>
</div>
</div>
{/* Content Area */}
<div className="p-6 md:p-8 flex-1 flex flex-col">
<h3 className="text-xl md:text-2xl font-bold text-slate-800 mb-3 group-hover:text-indigo-600 transition-colors">
{project.title[lang]}
</h3>
<p className="text-base text-slate-600 leading-relaxed mb-6 flex-1">
{project.description[lang]}
</p>
<div className="mt-auto pt-6 border-t border-slate-100 flex items-center justify-between">
<div className="flex gap-2">
{/* Decorative dots representing tech stack */}
<div className="h-2 w-2 rounded-full bg-indigo-500"></div>
<div className="h-2 w-2 rounded-full bg-blue-400"></div>
<div className="h-2 w-2 rounded-full bg-purple-400"></div>
</div>
{project.link && (
<a
href={project.link}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 text-sm font-bold text-indigo-600 hover:text-indigo-800 transition-colors bg-indigo-50 px-4 py-2 rounded-lg hover:bg-indigo-100"
>
{project.linkText ? project.linkText[lang] : (lang === 'en' ? 'View details' : '查看详情')}
<ExternalLink size={16} />
</a>
)}
</div>
</div>
</div>
);
};
export default ProjectCard;