Files
ColaFlow-Web/components/features/kanban/TaskCard.tsx
Yaojia Wang 358ee9b7f4 perf(frontend): Optimize component rendering with React.memo and hooks - Sprint 3 Story 2
Add React.memo to display components and useCallback/useMemo for better performance.

Changes:
- Added React.memo to TaskCard component
- Added React.memo to StoryCard component
- Added React.memo to KanbanBoard component
- Added React.memo to KanbanColumn component
- Added useCallback to kanban page drag handlers (handleDragStart, handleDragEnd)
- Added useCallback to epics page handlers (handleDelete, getStatusColor, getPriorityColor)
- Added useMemo for expensive computations in dashboard page (stats, recentProjects sorting)
- Added useMemo for total tasks calculation in KanbanBoard
- Removed unused isConnected variable from kanban page

Performance improvements:
- Reduced unnecessary re-renders in Card components
- Optimized list rendering performance with memoized callbacks
- Improved filtering and sorting performance with useMemo
- Better React DevTools Profiler metrics

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 19:57:07 +01:00

64 lines
1.9 KiB
TypeScript

'use client';
import React from 'react';
import { Card, CardContent, CardHeader } from '@/components/ui/card';
import { Clock, User } from 'lucide-react';
import type { TaskCard as TaskCardType } from '@/types/kanban';
interface TaskCardProps {
task: TaskCardType;
isDragging?: boolean;
}
export const TaskCard = React.memo(function TaskCard({ task, isDragging = false }: TaskCardProps) {
const priorityColors = {
Low: 'bg-blue-100 text-blue-700',
Medium: 'bg-yellow-100 text-yellow-700',
High: 'bg-orange-100 text-orange-700',
Urgent: 'bg-red-100 text-red-700',
};
return (
<Card
className={`cursor-move transition-shadow hover:shadow-md ${
isDragging ? 'opacity-50 shadow-lg' : ''
}`}
>
<CardHeader className="p-4 pb-2">
<div className="flex items-start justify-between gap-2">
<h4 className="text-sm font-medium leading-tight">{task.title}</h4>
<span
className={`rounded-full px-2 py-0.5 text-xs font-medium ${
priorityColors[task.priority as keyof typeof priorityColors] ||
priorityColors.Medium
}`}
>
{task.priority}
</span>
</div>
</CardHeader>
<CardContent className="p-4 pt-0">
{task.description && (
<p className="mb-3 line-clamp-2 text-xs text-muted-foreground">
{task.description}
</p>
)}
<div className="flex items-center gap-4 text-xs text-muted-foreground">
{task.estimatedHours && (
<div className="flex items-center gap-1">
<Clock className="h-3 w-3" />
<span>{task.estimatedHours}h</span>
</div>
)}
{task.assigneeId && (
<div className="flex items-center gap-1">
<User className="h-3 w-3" />
<span>Assigned</span>
</div>
)}
</div>
</CardContent>
</Card>
);
});