()
| 18 | }; |
| 19 | |
| 20 | const RecentActivity = () => { |
| 21 | const [tasks, setTasks] = useState([]); |
| 22 | const { currentWorkspace } = useSelector((state) => state.workspace); |
| 23 | |
| 24 | const getTasksFromCurrentWorkspace = () => { |
| 25 | |
| 26 | if (!currentWorkspace) return; |
| 27 | |
| 28 | const tasks = currentWorkspace.projects.flatMap((project) => project.tasks.map((task) => task)); |
| 29 | setTasks(tasks); |
| 30 | }; |
| 31 | |
| 32 | useEffect(() => { |
| 33 | getTasksFromCurrentWorkspace(); |
| 34 | }, [currentWorkspace]); |
| 35 | |
| 36 | return ( |
| 37 | <div 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 rounded-lg transition-all overflow-hidden"> |
| 38 | <div className="border-b border-zinc-200 dark:border-zinc-800 p-4"> |
| 39 | <h2 className="text-lg text-zinc-800 dark:text-zinc-200">Recent Activity</h2> |
| 40 | </div> |
| 41 | |
| 42 | <div className="p-0"> |
| 43 | {tasks.length === 0 ? ( |
| 44 | <div className="p-12 text-center"> |
| 45 | <div className="w-16 h-16 mx-auto mb-4 bg-zinc-200 dark:bg-zinc-800 rounded-full flex items-center justify-center"> |
| 46 | <Clock className="w-8 h-8 text-zinc-600 dark:text-zinc-500" /> |
| 47 | </div> |
| 48 | <p className="text-zinc-600 dark:text-zinc-400">No recent activity</p> |
| 49 | </div> |
| 50 | ) : ( |
| 51 | <div className="divide-y divide-zinc-200 dark:divide-zinc-800"> |
| 52 | {tasks.map((task) => { |
| 53 | const TypeIcon = typeIcons[task.type]?.icon || Square; |
| 54 | const iconColor = typeIcons[task.type]?.color || "text-gray-500 dark:text-gray-400"; |
| 55 | |
| 56 | return ( |
| 57 | <div key={task.id} className="p-6 hover:bg-zinc-50 dark:hover:bg-zinc-900/50 transition-colors"> |
| 58 | <div className="flex items-start gap-4"> |
| 59 | <div className="p-2 bg-zinc-200 dark:bg-zinc-800 rounded-lg"> |
| 60 | <TypeIcon className={`w-4 h-4 ${iconColor}`} /> |
| 61 | </div> |
| 62 | <div className="flex-1 min-w-0"> |
| 63 | <div className="flex items-start justify-between mb-2"> |
| 64 | <h4 className="text-zinc-800 dark:text-zinc-200 truncate"> |
| 65 | {task.title} |
| 66 | </h4> |
| 67 | <span className={`ml-2 px-2 py-1 rounded text-xs ${statusColors[task.status] || "bg-zinc-300 text-zinc-700 dark:bg-zinc-700 dark:text-zinc-300"}`}> |
| 68 | {task.status.replace("_", " ")} |
| 69 | </span> |
| 70 | </div> |
| 71 | <div className="flex items-center gap-3 text-xs text-zinc-500 dark:text-zinc-400"> |
| 72 | <span className="capitalize">{task.type.toLowerCase()}</span> |
| 73 | {task.assignee && ( |
| 74 | <div className="flex items-center gap-1"> |
| 75 | <div className="w-4 h-4 bg-zinc-300 dark:bg-zinc-700 rounded-full flex items-center justify-center text-[10px] text-zinc-800 dark:text-zinc-200"> |
| 76 | {task.assignee.name[0].toUpperCase()} |
| 77 | </div> |
nothing calls this directly
no test coverage detected