Skip to content

Commit 01f4581

Browse files
feat: add ActivityCard component
Create ActivityCard.tsx to render an activity summary card with status-driven styles and badges. Uses ActivityWithRelations and ActivityStatus types, react-icons (FaTasks, FaClock) and react-router Link to /activities/:id. Displays project, description, due date and a status-specific visual treatment for in_progress, done, expired and pending states.
1 parent 6c5b248 commit 01f4581

1 file changed

Lines changed: 86 additions & 0 deletions

File tree

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { Link } from 'react-router-dom';
2+
import { FaTasks, FaClock } from 'react-icons/fa';
3+
import type { ActivityWithRelations } from '../../types/Activity/Activity';
4+
import type { ActivityStatus } from '../../constants/ActivityStatus';
5+
6+
type ActivityCardProps = {
7+
activity: ActivityWithRelations;
8+
}
9+
10+
export function ActivityCard({
11+
activity,
12+
}: ActivityCardProps) {
13+
14+
const getStatusStyles = (status: ActivityStatus) => {
15+
switch (status) {
16+
case 'in_progress':
17+
return {
18+
card: 'bg-white border-slate-200 border-l-4 border-l-blue-500',
19+
badge: 'bg-blue-100 text-blue-700',
20+
label: 'Em Progresso',
21+
icon: 'text-blue-500',
22+
time: 'text-slate-500',
23+
divider: 'border-slate-100'
24+
};
25+
case 'done':
26+
return {
27+
card: 'bg-white border-slate-200',
28+
badge: 'bg-gray-100 text-gray-700',
29+
label: 'Finalizado',
30+
icon: 'text-gray-400',
31+
time: 'text-slate-500',
32+
divider: 'border-slate-100'
33+
};
34+
case 'expired':
35+
return {
36+
card: 'bg-red-50/30 border-red-200',
37+
badge: 'bg-red-100 text-red-700',
38+
label: 'Expirado',
39+
icon: 'text-red-400',
40+
time: 'text-red-500',
41+
divider: 'border-red-100'
42+
};
43+
default:
44+
return {
45+
card: 'bg-white border-slate-200',
46+
badge: 'bg-yellow-100 text-yellow-700',
47+
label: 'Pendente',
48+
icon: 'text-slate-400',
49+
time: 'text-slate-500',
50+
divider: 'border-slate-100'
51+
};
52+
}
53+
};
54+
55+
const styles = getStatusStyles(activity.status);
56+
57+
return (
58+
<div className={`w-75 h-55 flex flex-col justify-between p-5 rounded-xl border shadow-sm shrink-0 hover:shadow-md transition-shadow ${styles.card}`}>
59+
<div>
60+
<div className="flex justify-between items-center mb-3">
61+
<span className={`px-2.5 py-1 text-xs font-semibold rounded-md ${styles.badge}`}>
62+
{styles.label}
63+
</span>
64+
<FaTasks className={styles.icon} />
65+
</div>
66+
<h3 className="text-base font-bold text-slate-900 mb-1 truncate" title={activity.name}>
67+
{activity.name}
68+
</h3>
69+
<p className="text-xs text-slate-500 truncate mb-2" title={`Projeto: ${activity.project.name}`}>
70+
Projeto: {activity.project.name}
71+
</p>
72+
<p className="text-sm text-slate-600 line-clamp-2" title={activity.description ? activity.description : "Sem descrição"}>
73+
{activity.description ? activity.description : "Sem descrição"}
74+
</p>
75+
</div>
76+
<div className={`flex items-center justify-between pt-3 border-t mt-4 ${styles.divider}`}>
77+
<span className={`text-xs font-medium flex items-center gap-1 truncate max-w-35 ${styles.time}`} title={activity.due_date}>
78+
<FaClock className="shrink-0" /> {activity.due_date}
79+
</span>
80+
<Link to={`/activities/${activity.id}`} className="text-xs font-semibold text-blue-600 hover:text-blue-800 shrink-0">
81+
Ver detalhes
82+
</Link>
83+
</div>
84+
</div>
85+
);
86+
}

0 commit comments

Comments
 (0)