import { DashboardLayout } from "@/components/layout/sidebar"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Separator } from "@/components/ui/separator"; import { CheckCircle2, Circle, Clock, AlertCircle, TrendingUp, ExternalLink, ArrowRight, Calendar, AlertTriangle, User, Layers, } from "lucide-react"; import Link from "next/link"; import { fetchRecentlyUpdatedTasks, fetchRecentlyCompletedTasks, fetchHighPriorityOpenTasks, getTaskStatusCounts, countHighPriorityTasks, countOverdueTasks, Task, } from "@/lib/data/tasks"; // Force dynamic rendering to fetch fresh data from Supabase on each request export const dynamic = "force-dynamic"; // Helper functions function formatRelativeTime(dateString: string): string { const date = new Date(dateString); const now = new Date(); const diffMs = now.getTime() - date.getTime(); const diffMins = Math.floor(diffMs / (1000 * 60)); const diffHours = Math.floor(diffMs / (1000 * 60 * 60)); const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); if (diffMins < 60) return `${diffMins}m ago`; if (diffHours < 24) return `${diffHours}h ago`; if (diffDays < 7) return `${diffDays}d ago`; return date.toLocaleDateString("en-US", { month: "short", day: "numeric" }); } function getPriorityColor(priority: string): string { switch (priority) { case "urgent": return "bg-red-500/15 text-red-400 border-red-500/30"; case "high": return "bg-orange-500/15 text-orange-400 border-orange-500/30"; case "medium": return "bg-yellow-500/15 text-yellow-400 border-yellow-500/30"; default: return "bg-blue-500/15 text-blue-400 border-blue-500/30"; } } function getStatusIcon(status: string) { switch (status) { case "done": return ; case "in-progress": return ; case "review": case "validate": return ; default: return ; } } function getStatusLabel(status: string): string { switch (status) { case "open": case "todo": return "Open"; case "in-progress": return "In Progress"; case "review": case "validate": return "Review"; case "done": return "Done"; case "blocked": return "Blocked"; case "archived": return "Archived"; case "canceled": return "Canceled"; default: return status; } } // Task list item component function TaskListItem({ task }: { task: Task }) { return (
{getStatusIcon(task.status)}

{task.title}

{formatRelativeTime(task.updatedAt)} {task.assigneeName && ( {task.assigneeName} )}
{task.priority}
); } // Stat card component function StatCard({ title, value, subtitle, icon: Icon, colorClass, }: { title: string; value: string | number; subtitle?: string; icon: React.ElementType; colorClass: string; }) { return (

{title}

{value}

{subtitle &&

{subtitle}

}
); } // Status breakdown card function StatusBreakdownCard({ counts }: { counts: { open: number; inProgress: number; review: number; done: number; total: number } }) { return ( Tasks by Status
Open
{counts.open}
In Progress
{counts.inProgress}
Review
{counts.review}
Done
{counts.done}
Total {counts.total}
); } export default async function TasksOverviewPage() { // Fetch all data in parallel with error handling let statusCounts = { open: 0, inProgress: 0, review: 0, done: 0, total: 0 }; let highPriorityCount = 0; let overdueCount = 0; let recentlyUpdated: Task[] = []; let recentlyCompleted: Task[] = []; let highPriorityOpen: Task[] = []; let errorMessage: string | null = null; try { [ statusCounts, highPriorityCount, overdueCount, recentlyUpdated, recentlyCompleted, highPriorityOpen, ] = await Promise.all([ getTaskStatusCounts(), countHighPriorityTasks(), countOverdueTasks(), fetchRecentlyUpdatedTasks(5), fetchRecentlyCompletedTasks(5), fetchHighPriorityOpenTasks(5), ]); } catch (error) { console.error("Error fetching tasks:", error); errorMessage = error instanceof Error ? error.message : "Failed to load tasks"; } return (
{/* Header */}

Tasks Overview

Mission Control view of all tasks. Manage work in{" "} gantt-board

{/* Error Message */} {errorMessage && (

Error loading tasks

{errorMessage}

Make sure you are logged into gantt-board and have access to the Supabase database.

)} {/* Stats Section */}
{/* Recent Activity Section */}
{/* Recently Updated */} Recently Updated {recentlyUpdated.length > 0 ? (
{recentlyUpdated.map((task) => ( ))}
) : (

No recently updated tasks

)}
{/* Recently Completed */} Recently Completed {recentlyCompleted.length > 0 ? (
{recentlyCompleted.map((task) => ( ))}
) : (

No recently completed tasks

)}
{/* High Priority Open Tasks */} High Priority Open {highPriorityOpen.length > 0 ? (
{highPriorityOpen.map((task) => ( ))}
) : (

No high priority open tasks

)}
{/* Bottom Section: Status Breakdown + Quick Actions */}
{/* Status Breakdown */} {/* Quick Actions */} Quick Actions

Task Management

Mission Control is read-only. All task creation and editing happens in gantt-board.

); }