"use client"; import { useRouter, useSearchParams } from "next/navigation"; import Link from "next/link"; import { Badge } from "@/components/ui/badge"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { cn, getInitials } from "@/lib/utils"; import { CalendarDays, ListTodo, AlertTriangle, Eye, Clock, Layers, } from "lucide-react"; import { formatDistanceToNow } from "date-fns"; import { TASK_STATUS_CONFIG, TASK_TYPE_LABELS } from "@/components/tasks/TaskCard"; import { TaskStatus, TaskType } from "@prisma/client"; const PRIORITY_DOT: Record = { LOW: "bg-zinc-500", NORMAL: "bg-blue-500", HIGH: "bg-amber-500", URGENT: "bg-red-500", }; interface Artist { id: string; name: string | null; email: string; } interface Task { id: string; title: string; type: TaskType; status: TaskStatus; priority: string; dueDate: Date | null; shot?: { id: string; shotCode: string } | null; asset?: { id: string; assetCode: string; name: string } | null; project: { id: string; name: string; code: string }; assignedArtist?: { id: string; name: string | null; email: string; image: string | null } | null; _count?: { versions: number }; versions?: { id: string; versionNumber: number; approvalStatus: string; createdAt: Date }[]; } interface TasksPageClientProps { tasks: Task[]; artists: Artist[]; currentUserId: string; role: string; counts: { today: number; overdue: number; inReview: number; total: number }; activeStatus?: string; activeAssignee?: string; } const FILTER_TABS = [ { label: "All", status: undefined, icon: ListTodo, color: "text-zinc-400" }, { label: "Due Today", status: "today", icon: Clock, color: "text-amber-400" }, { label: "Overdue", status: "overdue", icon: AlertTriangle, color: "text-red-400" }, { label: "In Review", status: "INTERNAL_REVIEW", icon: Eye, color: "text-purple-400" }, ]; export function TasksPageClient({ tasks, artists, currentUserId, role, counts, activeStatus, activeAssignee, }: TasksPageClientProps) { const router = useRouter(); const isArtist = role === "ARTIST"; const now = new Date(); const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate()); // Client-side filter const filtered = tasks.filter((task) => { if (activeStatus === "today") { return ( task.dueDate && new Date(task.dueDate) >= todayStart && new Date(task.dueDate) < new Date(todayStart.getTime() + 86400000) && task.status !== "DONE" ); } if (activeStatus === "overdue") { return task.dueDate && new Date(task.dueDate) < todayStart && task.status !== "DONE"; } if (activeStatus === "INTERNAL_REVIEW") { return ["INTERNAL_REVIEW", "CLIENT_REVIEW"].includes(task.status); } return true; }); const navigate = (params: { status?: string; assignee?: string }) => { const sp = new URLSearchParams(); if (params.status) sp.set("status", params.status); if (params.assignee) sp.set("assignee", params.assignee); router.push(`/tasks?${sp.toString()}`); }; return (
{/* Header */}

{isArtist ? "My Tasks" : "All Tasks"}

{counts.total} total · {counts.overdue > 0 && ( {counts.overdue} overdue · )} {counts.inReview} in review

{/* Assignee filter (non-artists) */} {!isArtist && artists.length > 0 && ( )}
{/* Filter tabs */}
{FILTER_TABS.map((tab) => { const Icon = tab.icon; const isActive = (!activeStatus && !tab.status) || activeStatus === tab.status; const count = tab.status === "today" ? counts.today : tab.status === "overdue" ? counts.overdue : tab.status === "INTERNAL_REVIEW" ? counts.inReview : counts.total; return ( ); })}
{/* Task list */} {filtered.length === 0 ? (

No tasks found

) : (
{filtered.map((task) => { const cfg = TASK_STATUS_CONFIG[task.status]; const Icon = cfg.icon; const contextCode = task.shot?.shotCode ?? task.asset?.assetCode; const isOverdue = task.dueDate && new Date(task.dueDate) < now && task.status !== "DONE"; const latestVersion = task.versions?.[0]; return ( {/* Priority dot */} {/* Title + context */}
{task.title} {contextCode && ( {contextCode} )}
{TASK_TYPE_LABELS[task.type]} · {task.project.name}
{/* Meta */}
{latestVersion && ( v{latestVersion.versionNumber} )} {(task._count?.versions ?? 0) > 0 && ( {task._count!.versions} )} {task.dueDate && ( {formatDistanceToNow(new Date(task.dueDate), { addSuffix: true })} )} {task.assignedArtist && ( {getInitials(task.assignedArtist.name ?? task.assignedArtist.email)} )} {cfg.label}
); })}
)}
); }