FlowWeb / src /features /dashboard /components /ProjectCard.jsx
danylokhodus's picture
init
de55c35
Raw
History Blame Contribute Delete
3.18 kB
import React, { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { PenTool, MoreVertical, Clock, ExternalLink, Trash2 } from 'lucide-react';
const ProjectCard = ({ project, onDelete }) => {
const navigate = useNavigate();
const [showMenu, setShowMenu] = useState(false);
const { t } = useTranslation();
return (
<motion.div
whileHover={{ y: -5, rotate: 0.5 }}
className="bg-surface-container-lowest p-6 rough-border rough-shadow cursor-pointer group flex flex-col gap-4 relative"
onClick={() => navigate(`/canvas/${project.id}`)}
>
<div className="flex justify-between items-start">
<div className={`w-12 h-12 rounded-lg bg-primary/10 rough-border flex items-center justify-center`}>
<PenTool size={24} className="text-primary" />
</div>
<div className="relative">
<button
onClick={(e) => { e.stopPropagation(); setShowMenu(!showMenu); }}
className="text-on-surface-variant hover:text-primary p-1 rounded-full hover:bg-surface-variant"
>
<MoreVertical size={20} />
</button>
<AnimatePresence>
{showMenu && (
<motion.div
initial={{ opacity: 0, scale: 0.9, y: -10 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.9, y: -10 }}
className="absolute right-0 mt-2 w-48 bg-surface-container-lowest rough-border rough-shadow z-50 overflow-hidden"
>
<button
onClick={(e) => { e.stopPropagation(); navigate(`/canvas/${project.id}`); }}
className="w-full text-left px-4 py-3 flex items-center gap-3 hover:bg-surface-variant transition-colors text-on-surface font-bold border-b-2 border-primary/5"
>
<ExternalLink size={18} /> {t('dashboard.open_sketch', 'Open Sketch')}
</button>
<button
onClick={(e) => { e.stopPropagation(); onDelete(project.id); setShowMenu(false); }}
className="w-full text-left px-4 py-3 flex items-center gap-3 hover:bg-red-500/10 text-red-500 transition-colors font-bold"
>
<Trash2 size={18} /> {t('dashboard.delete')}
</button>
</motion.div>
)}
</AnimatePresence>
</div>
</div>
<div>
<h3 className="text-3xl font-display-lg text-primary line-clamp-1">{project.title}</h3>
<p className="text-sm text-on-surface-variant flex items-center gap-1 mt-1">
<Clock size={14} /> {new Date(project.createdAt).toLocaleDateString()}
</p>
</div>
<div className="mt-2">
<p className="text-sm text-on-surface-variant line-clamp-2 italic opacity-70">
{project.description || t('dashboard.no_description', 'No description provided...')}
</p>
</div>
</motion.div>
);
};
export default ProjectCard;