Update Tasks.tsx

This commit is contained in:
Desktop
2025-11-12 23:06:44 +05:00
parent 459cabf921
commit 559bde5d19

View File

@@ -29,15 +29,9 @@ import { TaskIcon, PlusIcon, DownloadIcon } from '../../icons';
import { createTasksPageConfig } from '../../config/pages/tasks.config'; import { createTasksPageConfig } from '../../config/pages/tasks.config';
import { useSectorStore } from '../../store/sectorStore'; import { useSectorStore } from '../../store/sectorStore';
import { usePageSizeStore } from '../../store/pageSizeStore'; import { usePageSizeStore } from '../../store/pageSizeStore';
import ViewToggle, { ViewType } from '../../components/common/ViewToggle';
import { KanbanBoard, TaskList, Task as KanbanTask } from '../../components/tasks';
import WorkflowPipeline, { WorkflowStep } from '../../components/dashboard/WorkflowPipeline';
import ComponentCard from '../../components/common/ComponentCard';
import { useNavigate } from 'react-router';
import PageHeader from '../../components/common/PageHeader'; import PageHeader from '../../components/common/PageHeader';
export default function Tasks() { export default function Tasks() {
const navigate = useNavigate();
const toast = useToast(); const toast = useToast();
const { activeSector } = useSectorStore(); const { activeSector } = useSectorStore();
const { pageSize } = usePageSizeStore(); const { pageSize } = usePageSizeStore();
@@ -65,9 +59,6 @@ export default function Tasks() {
const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('desc'); const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('desc');
const [showContent, setShowContent] = useState(false); const [showContent, setShowContent] = useState(false);
// View state
const [currentView, setCurrentView] = useState<ViewType>('table');
// Modal state // Modal state
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
const [isEditMode, setIsEditMode] = useState(false); const [isEditMode, setIsEditMode] = useState(false);
@@ -193,52 +184,6 @@ export default function Tasks() {
setCurrentPage(1); setCurrentPage(1);
}, [pageSize]); }, [pageSize]);
// Map API Task to KanbanBoard Task
const mapTaskToKanbanTask = (task: Task): KanbanTask => {
// Map status from API to Kanban status
const statusMap: Record<string, "todo" | "in_progress" | "completed"> = {
'queued': 'todo',
'in_progress': 'in_progress',
'generating': 'in_progress',
'completed': 'completed',
'published': 'completed',
'draft': 'todo',
'review': 'in_progress',
};
const kanbanStatus = statusMap[task.status] || 'todo';
// Format due date if available (you might need to add this field to Task)
const dueDate = task.created_at ? new Date(task.created_at).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric'
}) : undefined;
// Parse keywords if available (comma-separated string)
const keywordNames = task.keywords ? task.keywords.split(',').map(k => k.trim()).filter(k => k) : undefined;
return {
id: String(task.id),
title: task.title || 'Untitled Task',
status: kanbanStatus,
dueDate,
commentsCount: 0, // Add if you have this data
attachmentsCount: 0, // Add if you have this data
tags: task.cluster_name ? [{ label: task.cluster_name, color: 'brand' as const }] : undefined,
description: task.description || undefined,
assignee: undefined, // Add if you have assignee data
// Relationship data
clusterId: task.cluster_id || null,
clusterName: task.cluster_name || null,
ideaId: task.idea_id || null,
ideaTitle: task.idea_title || null,
keywordIds: undefined, // API doesn't return keyword IDs directly, would need to fetch
keywordNames: keywordNames,
};
};
const kanbanTasks = useMemo(() => tasks.map(mapTaskToKanbanTask), [tasks]);
// Debounced search // Debounced search
useEffect(() => { useEffect(() => {
@@ -602,115 +547,13 @@ export default function Tasks() {
} }
}; };
const handleTaskClick = (kanbanTask: KanbanTask) => {
const apiTask = tasks.find(t => String(t.id) === kanbanTask.id);
if (apiTask) {
setEditingTask(apiTask);
setFormData({
title: apiTask.title || '',
description: apiTask.description || '',
keywords: apiTask.keywords || '',
cluster_id: apiTask.cluster_id || null,
content_structure: apiTask.content_structure || 'blog_post',
content_type: apiTask.content_type || 'blog_post',
status: apiTask.status || 'queued',
word_count: apiTask.word_count || 0,
});
setIsEditMode(true);
setIsModalOpen(true);
}
};
const handleTaskMove = async (taskId: string, newStatus: "todo" | "in_progress" | "completed") => {
const apiTask = tasks.find(t => String(t.id) === taskId);
if (!apiTask) return;
// Map Kanban status back to API status
const statusMap: Record<string, string> = {
'todo': 'queued',
'in_progress': 'in_progress',
'completed': 'completed',
};
try {
await updateTask(apiTask.id, { status: statusMap[newStatus] || 'queued' });
toast.success('Task status updated');
loadTasks();
} catch (error: any) {
toast.error(`Failed to update task: ${error.message}`);
}
};
// Calculate workflow steps for Tasks page
const todoCount = tasks.filter(t => t.status === 'queued' || t.status === 'draft').length;
const inProgressCount = tasks.filter(t => t.status === 'in_progress' || t.status === 'generating' || t.status === 'review').length;
const completedCount = tasks.filter(t => t.status === 'completed' || t.status === 'published').length;
const contentCount = tasks.filter(t => t.content && t.content.length > 0).length;
const workflowSteps: WorkflowStep[] = [
{
number: 1,
title: "Queue Tasks",
status: todoCount > 0 ? "completed" : "pending",
count: todoCount,
path: "/writer/tasks",
description: "Tasks queued for content generation",
},
{
number: 2,
title: "Generate Content",
status: inProgressCount > 0 ? "in_progress" : contentCount > 0 ? "completed" : "pending",
count: contentCount,
path: "/writer/tasks",
description: "AI content generation",
},
{
number: 3,
title: "Review & Edit",
status: tasks.filter(t => t.status === 'review').length > 0 ? "in_progress" : "pending",
count: tasks.filter(t => t.status === 'review').length,
path: "/writer/content",
description: "Content review and editing",
},
{
number: 4,
title: "Publish",
status: completedCount > 0 ? "completed" : "pending",
count: completedCount,
path: "/writer/content",
description: "Published content",
},
];
return ( return (
<> <>
{/* Workflow Pipeline - Show for all views */} <PageHeader
<div className="mb-6"> title="Tasks"
<ComponentCard title="Content Creation Workflow" desc="Track your content creation progress"> badge={{ icon: <TaskIcon />, color: 'indigo' }}
<WorkflowPipeline />
steps={workflowSteps} <TablePageTemplate
onStepClick={(step) => {
navigate(step.path);
}}
showConnections={true}
/>
</ComponentCard>
</div>
{/* View Toggle - Only show for Kanban/List views */}
{currentView !== 'table' && (
<div className="mb-4 flex items-center justify-end">
<ViewToggle currentView={currentView} onViewChange={setCurrentView} />
</div>
)}
{/* Table View */}
{currentView === 'table' && (
<>
<div className="mb-4 flex justify-end">
<ViewToggle currentView={currentView} onViewChange={setCurrentView} />
</div>
<TablePageTemplate
hideHeader={true} hideHeader={true}
columns={pageConfig.columns} columns={pageConfig.columns}
data={tasks} data={tasks}
@@ -811,69 +654,6 @@ export default function Tasks() {
setCurrentPage(1); setCurrentPage(1);
}} }}
/> />
</>
)}
{/* Kanban View */}
{currentView === 'kanban' && (
<KanbanBoard
tasks={kanbanTasks}
onTaskClick={handleTaskClick}
onTaskMove={handleTaskMove}
onAddTask={() => {
resetForm();
setIsModalOpen(true);
}}
onFilterChange={(filter) => {
// Map filter to status filter
const statusMap: Record<string, string> = {
'All': '',
'Todo': 'queued',
'InProgress': 'in_progress',
'Completed': 'completed',
};
setStatusFilter(statusMap[filter] || '');
setCurrentPage(1);
loadTasks();
}}
/>
)}
{/* List View */}
{currentView === 'list' && (
<TaskList
tasks={kanbanTasks}
onTaskClick={handleTaskClick}
onTaskToggle={async (taskId, completed) => {
const apiTask = tasks.find(t => String(t.id) === taskId);
if (apiTask) {
try {
await updateTask(apiTask.id, { status: completed ? 'completed' : 'queued' });
toast.success('Task updated');
loadTasks();
} catch (error: any) {
toast.error(`Failed to update task: ${error.message}`);
}
}
}}
onAddTask={() => {
resetForm();
setIsModalOpen(true);
}}
onFilterChange={(filter) => {
// Map filter to status filter
const statusMap: Record<string, string> = {
'All': '',
'Todo': 'queued',
'InProgress': 'in_progress',
'Completed': 'completed',
};
setStatusFilter(statusMap[filter] || '');
setCurrentPage(1);
loadTasks();
}}
/>
)}
{/* Progress Modal for AI Functions */} {/* Progress Modal for AI Functions */}
<ProgressModal <ProgressModal