'use client'; import { useEffect, useState } from 'react'; import Link from 'next/link'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { StatusBadge } from '@/components/status-badge'; import { useUser } from '@/components/user-context'; import { formatDateRange } from '@/lib/kr-utils'; import type { Task, TaskStep, User } from '@/types/database'; import { CheckSquare, Clock, Calendar, AlertTriangle, User as UserIcon, Plus } from 'lucide-react'; import { TaskEditDialog } from '@/components/task-edit-dialog'; import { toast } from 'sonner'; import { fetchApi } from '@/lib/api-client'; interface TaskWithRelations extends Task { steps: TaskStep[]; owner: User | null; // We might want project info too, but the API doesn't return it joined yet. // We can fetch projects separately or just show task details. } interface HelpStepWithRelations extends TaskStep { task: Pick | null; } export default function MyTasksPage() { const { currentUser, users } = useUser(); const [tasks, setTasks] = useState([]); const [helpSteps, setHelpSteps] = useState([]); const [isLoading, setIsLoading] = useState(true); // Dialog state const [isTaskDialogOpen, setIsTaskDialogOpen] = useState(false); const [editingTask, setEditingTask] = useState<(Task & { steps: TaskStep[] }) | null>(null); const fetchTasks = async () => { try { const isOwnerView = currentUser?.role === 'owner'; const url = isOwnerView ? '/api/tasks' : `/api/tasks?user_id=${currentUser?.id}&include_help=true`; const res = await fetchApi(url); if (res.ok) { const data = await res.json(); // Enrich with owner info locally since API doesn't join const enrichedData = data.map((t: any) => ({ ...t, owner: users.find(u => u.id === t.owner_user_id) || null })); setTasks(enrichedData); } } catch (error) { console.error('Failed to fetch tasks:', error); } finally { setIsLoading(false); } }; const fetchHelpSteps = async () => { if (!currentUser?.id || currentUser.role === 'owner') return; try { const res = await fetchApi(`/api/task-steps?help_requested_to_user_id=${currentUser.id}`); if (res.ok) { const data = await res.json(); setHelpSteps(data); } } catch (error) { console.error('Failed to fetch help steps:', error); } }; useEffect(() => { if (users.length > 0 && currentUser) { fetchTasks(); fetchHelpSteps(); } }, [users, currentUser]); const handleTaskStatusChange = async (taskId: string, newStatus: string) => { try { const res = await fetchApi(`/api/tasks/${taskId}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status: newStatus }), }); if (res.ok) { setTasks(tasks.map(t => t.id === taskId ? { ...t, status: newStatus as any } : t)); toast.success('计划状态已更新'); } } catch (error) { toast.error('更新失败'); } }; // Group Tasks by owner for owner view const tasksByOwner = users.map(user => ({ user, tasks: tasks.filter(t => t.owner_user_id === user.id && t.status !== 'done') })).filter(group => group.tasks.length > 0 || group.user.role !== 'owner') .sort((a, b) => { if (a.tasks.length > 0 && b.tasks.length === 0) return -1; if (a.tasks.length === 0 && b.tasks.length > 0) return 1; return 0; }); const myTasks = tasks.filter(t => t.owner_user_id === currentUser?.id); const incomingHelpTasks = tasks.filter(t => t.help_requested_to_user_id === currentUser?.id && t.owner_user_id !== currentUser?.id); const activeTasks = myTasks.filter(t => t.status !== 'done'); const completedTasks = myTasks.filter(t => t.status === 'done'); // "Pending" tasks can be defined as todo/in_progress/expected const todoTasks = activeTasks.filter(t => t.status === 'todo'); const inProgressTasks = activeTasks.filter(t => t.status === 'in_progress'); const isOwner = currentUser?.role === 'owner'; if (isLoading) { return (
{[1, 2, 3].map(i => (
))}
); } return (

{isOwner ? '全员计划概览' : '我的计划'}

{isOwner ? '查看所有成员的计划执行情况' : `${currentUser?.name} 的计划清单` }

{!isOwner && ( )}
{isOwner ? (
{tasksByOwner.map(({ user, tasks }) => (
{user.name[0]}

{user.name}

{tasks.length} 个进行中的计划

{tasks.length === 0 ? (

暂无进行中的计划

) : (
{tasks.map(task => ( { setEditingTask(task); setIsTaskDialogOpen(true); }} /> ))}
)}
))} {tasksByOwner.length === 0 && (

没有任何成员有正在进行的计划

)}
) : ( <>

{activeTasks.length}

待完成

{inProgressTasks.length}

进行中

{activeTasks.filter(t => t.priority >= 4).length}

高优先级

进行中 ({activeTasks.length}) 协助我的计划 ({incomingHelpTasks.length}) 协助我的步骤 ({helpSteps.length}) 已完成 ({completedTasks.length}) 全部 ({myTasks.length}) {activeTasks.length === 0 ? (

暂无进行中的计划

) : ( activeTasks.map(task => ( { setEditingTask(task); setIsTaskDialogOpen(true); }} /> )) )}
{incomingHelpTasks.length === 0 ? (

暂无需要你协助的计划

) : ( incomingHelpTasks.map(task => ( { setEditingTask(task); setIsTaskDialogOpen(true); }} variant="help" /> )) )}
{helpSteps.length === 0 ? (

暂无需要你协助的步骤

) : ( helpSteps.map(step => ( { if (step.task) { const task = tasks.find(t => t.id === step.task?.id); if (task) { setEditingTask(task); setIsTaskDialogOpen(true); } } }} >
协助步骤 {step.help_requested_by_user_id && ( 发起人:{users.find(u => u.id === step.help_requested_by_user_id)?.name || '未知'} )}

{step.content}

{step.task?.title && (

来自计划:{step.task.title}

)}
{formatDateRange(step.start_date || '', step.end_date || '')}
)) )}
{completedTasks.length === 0 ? (

暂无已完成的计划

) : ( completedTasks.map(task => ( { setEditingTask(task); setIsTaskDialogOpen(true); }} /> )) )}
{myTasks.length === 0 ? (

暂无计划

) : ( myTasks.map(task => ( { setEditingTask(task); setIsTaskDialogOpen(true); }} /> )) )}
)}
); } function TaskCard({ task, onStatusChange, onClick, variant }: { task: TaskWithRelations; onStatusChange: (id: string, status: string) => void; onClick: () => void; variant?: 'normal' | 'help' }) { const { currentUser, users } = useUser(); const isDone = task.status === 'done'; const isIncomingHelp = variant === 'help' || (task.help_requested_to_user_id && task.help_requested_to_user_id === currentUser?.id && task.owner_user_id !== currentUser?.id); const isOutgoingHelp = task.help_requested_to_user_id && task.owner_user_id === currentUser?.id; const requesterName = task.help_requested_by_user_id ? (users.find(u => u.id === task.help_requested_by_user_id)?.name || '未知') : null; const helperName = task.help_requested_to_user_id ? (users.find(u => u.id === task.help_requested_to_user_id)?.name || '未知') : null; return (
{ e.stopPropagation(); onStatusChange(task.id, isDone ? 'todo' : 'done'); }} >
{isDone && }

{task.title}

{(isIncomingHelp || isOutgoingHelp) && (
{isIncomingHelp ? '协助请求' : '已请求协助'} {isIncomingHelp && requesterName && ( 发起人:{requesterName} )} {isOutgoingHelp && helperName && ( 协助人:{helperName} )}
)}
{task.owner && ( {task.owner.name} )} {formatDateRange(task.start_date || '', task.end_date || '')} {task.steps.length > 0 && ( {task.steps.filter(s => s.is_completed).length}/{task.steps.length} 步骤 )}
); }