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
In Progress
{counts.inProgress}
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.
);
}