()
| 3 | import { useSelector } from "react-redux"; |
| 4 | |
| 5 | export default function TasksSummary() { |
| 6 | |
| 7 | const { currentWorkspace } = useSelector((state) => state.workspace); |
| 8 | const user = { id: 'user_1' } |
| 9 | const [tasks, setTasks] = useState([]); |
| 10 | |
| 11 | // Get all tasks for all projects in current workspace |
| 12 | useEffect(() => { |
| 13 | if (currentWorkspace) { |
| 14 | setTasks(currentWorkspace.projects.flatMap((project) => project.tasks)); |
| 15 | } |
| 16 | }, [currentWorkspace]); |
| 17 | |
| 18 | const myTasks = tasks.filter(i => i.assigneeId === user.id); |
| 19 | const overdueTasks = tasks.filter(t => t.due_date && new Date(t.due_date) < new Date() && t.status !== 'DONE'); |
| 20 | const inProgressIssues = tasks.filter(i => i.status === 'IN_PROGRESS'); |
| 21 | |
| 22 | const summaryCards = [ |
| 23 | { |
| 24 | title: "My Tasks", |
| 25 | count: myTasks.length, |
| 26 | icon: User, |
| 27 | color: "bg-emerald-100 text-emerald-800 dark:bg-emerald-950 dark:text-emerald-400", |
| 28 | items: myTasks.slice(0, 3) |
| 29 | }, |
| 30 | { |
| 31 | title: "Overdue", |
| 32 | count: overdueTasks.length, |
| 33 | icon: AlertTriangle, |
| 34 | color: "bg-red-100 text-red-800 dark:bg-red-950 dark:text-red-400", |
| 35 | items: overdueTasks.slice(0, 3) |
| 36 | }, |
| 37 | { |
| 38 | title: "In Progress", |
| 39 | count: inProgressIssues.length, |
| 40 | icon: Clock, |
| 41 | color: "bg-blue-100 text-blue-800 dark:bg-blue-950 dark:text-blue-400", |
| 42 | items: inProgressIssues.slice(0, 3) |
| 43 | } |
| 44 | ]; |
| 45 | |
| 46 | return ( |
| 47 | <div className="space-y-6"> |
| 48 | {summaryCards.map((card) => ( |
| 49 | <div key={card.title} className="bg-white dark:bg-zinc-950 dark:bg-gradient-to-br dark:from-zinc-800/70 dark:to-zinc-900/50 border border-zinc-200 dark:border-zinc-800 hover:border-zinc-300 dark:hover:border-zinc-700 transition-all duration-200 rounded-lg overflow-hidden"> |
| 50 | <div className="border-b border-zinc-200 dark:border-zinc-800 p-4 pb-3"> |
| 51 | <div className="flex items-center gap-3"> |
| 52 | <div className="p-2 bg-zinc-50 dark:bg-zinc-800 rounded-lg"> |
| 53 | <card.icon className="w-4 h-4 text-gray-500 dark:text-zinc-400" /> |
| 54 | </div> |
| 55 | <div className="flex items-center justify-between flex-1"> |
| 56 | <h3 className="text-sm font-medium text-gray-800 dark:text-white">{card.title}</h3> |
| 57 | <span className={`inline-block mt-1 px-2 py-1 rounded text-xs font-semibold ${card.color}`}> |
| 58 | {card.count} |
| 59 | </span> |
| 60 | </div> |
| 61 | </div> |
| 62 | </div> |
nothing calls this directly
no outgoing calls
no test coverage detected