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>
64 lines
1.9 KiB
TypeScript
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>
|
|
);
|
|
});
|