Skip to content

Commit

Permalink
Merge pull request #76 from birdup000/issue-75
Browse files Browse the repository at this point in the history
Fix #75: add all the components to the Task Panel
  • Loading branch information
birdup000 authored Dec 26, 2024
2 parents 65f0e20 + c367272 commit 6ac11e0
Showing 1 changed file with 189 additions and 22 deletions.
211 changes: 189 additions & 22 deletions app/components/TaskPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
"use client";

import React, { useEffect, useState } from 'react';
import { DragDropContext, DropResult } from '@hello-pangea/dnd';
import ExportMenu from './ExportMenu';
import { TaskList as TaskListComponent } from './TaskList';
import { ThemeProvider, useTheme, ThemeType } from '../hooks/useTheme';
import { useTasks } from '../hooks/useTasks';
import { useSearch } from '../hooks/useSearch';
import SearchBar from './SearchBar';
import { useKeyboardShortcuts } from '../hooks/useKeyboardShortcuts';
import ThemeSelector from './ThemeSelector';
import TaskForm from './TaskForm';
import AIAssistantPanel from './AIAssistantPanel';
import TaskAnalytics from './TaskAnalytics';
import TaskAutomation from './TaskAutomation';
import React, { useEffect, useState } from 'react';
import { DragDropContext, DropResult } from '@hello-pangea/dnd';
import ExportMenu from './ExportMenu';
import React, { useEffect, useState } from 'react';
import { DragDropContext, DropResult } from '@hello-pangea/dnd';
import ExportMenu from './ExportMenu';
Expand All @@ -21,6 +38,9 @@ import { useRouter } from 'next/navigation';
import { Task } from '../types/task';
import { colors } from '../config/colors';
import AGiXTConfig from './AGiXTConfig';
import { WorkspacePanel } from './WorkspacePanel';
import ViewSelector from './ViewSelector';
import { ViewType } from '../types/view';

const defaultTheme: ThemeType = {
primary: colors.primary.DEFAULT,
Expand All @@ -40,7 +60,7 @@ const defaultTheme: ThemeType = {
}
};

const TaskPanel: React.FC = () => {
const TaskPanel: React.FC = () =>{
const [mounted, setMounted] = useState(false);
const [isInitialized, setIsInitialized] = useState(false);
const [error, setError] = useState<string | null>(null);
Expand All @@ -53,12 +73,13 @@ const TaskPanel: React.FC = () => {
const [isAGiXTConfigOpen, setIsAGiXTConfigOpen] = useState(false);
const [selectedTask, setSelectedTask] = useState<Task | null>(null);
const [agixtConfig, setAgixtConfig] = useState({ backendUrl: '', authToken: '' });

const [currentView, setCurrentView] = useState<ViewType>('board');

const { tasks, addTask, updateTask, deleteTask, reorderTasks, lists } = useTasks({
remoteEnabled: false,
userId: 'anonymous'
});

const {
searchTerm,
setSearchTerm,
Expand Down Expand Up @@ -101,36 +122,36 @@ useEffect(() =>{
}, [token, noAuth]);

useKeyboardShortcuts({
onNewTask: () => setIsEditorOpen(true),
onSearch: () => document.getElementById('search-input')?.focus(),
onToggleView: () => {},
onDelete: () => {},
onDeleteTask: () => {}
onNewTask: () =>setIsEditorOpen(true),
onSearch: () =>document.getElementById('search-input')?.focus(),
onToggleView: () =>{},
onDelete: () =>{},
onDeleteTask: () =>{}
});

const onDragEnd = (result: DropResult) => {
const onDragEnd = (result: DropResult) =>{
if (!result.destination) return;

const sourceStatus = result.source.droppableId;
const destinationStatus = result.destination.droppableId;
const taskId = result.draggableId;

if (sourceStatus === destinationStatus) {
const listTasks = tasks.filter(t => t.status === sourceStatus);
const listTasks = tasks.filter(t =>t.status === sourceStatus);
const [movedTask] = listTasks.splice(result.source.index, 1);
listTasks.splice(result.destination.index, 0, movedTask);

const updatedTasks = tasks.map(t => {
const updatedTasks = tasks.map(t =>{
if (t.status === sourceStatus) {
const reorderedTask = listTasks.find(rt => rt.id === t.id);
const reorderedTask = listTasks.find(rt =>rt.id === t.id);
return reorderedTask || t;
}
return t;
});

reorderTasks(updatedTasks);
} else {
const task = tasks.find(t => t.id === taskId);
const task = tasks.find(t =>t.id === taskId);
if (!task) return;

const updatedTask = {
Expand All @@ -142,7 +163,7 @@ useEffect(() =>{
}
};

const handleTaskSuggestion = (taskSuggestion: Partial<Task>) => {
const handleTaskSuggestion = (taskSuggestion: Partial<Task>) =>{
const newTask: Task = {
id: Date.now().toString(),
title: taskSuggestion.title || '',
Expand All @@ -162,18 +183,164 @@ useEffect(() =>{
addTask(newTask);
};

const handleTaskOptimization = (taskIds: string[]) => {
const optimizedTasks = taskIds.map(id => tasks.find(t => t.id === id)).filter(Boolean) as Task[];
const handleTaskOptimization = (taskIds: string[]) =>{
const optimizedTasks = taskIds.map(id =>tasks.find(t =>t.id === id)).filter(Boolean) as Task[];
reorderTasks(optimizedTasks);
};

if (!mounted || !isInitialized) {
return (
<div className="flex items-center justify-center h-screen bg-[#111111] text-white">
<div className="text-center">
<div className="text-lg mb-2">Loading Task Panel...</div>
<div className="text-sm text-gray-400">Please wait while we set things up</div>
</div>
return (<div className="flex items-center justify-center h-screen bg-[#111111] text-white"><div className="text-center"><div className="text-lg mb-2">Loading Task Panel...</div><div className="text-sm text-gray-400">Please wait while we set things up</div></div></div>);
}

if (error) {
return (<div className="flex items-center justify-center h-screen bg-[#111111] text-white"><div className="text-center"><div className="text-lg mb-2 text-red-500">Error Loading Task Panel</div><div className="text-sm text-gray-400">{error}</div></div></div>);
}

return (<ThemeProvider value={{ theme, setTheme }}><div className="min-h-screen bg-[#111111] text-white p-4"><div className="flex"><div className="flex-1 max-w-7xl mx-auto"><header className="mb-8"><div className="flex justify-between items-center mb-4"><h1 className="text-2xl font-bold">Task Panel</h1><div className="flex items-center space-x-4"><ThemeSelector currentTheme={theme} onThemeChange={setTheme} /><button
onClick={() =>setIsAGiXTConfigOpen(true)}
className="px-4 py-2 bg-gray-600 hover:bg-gray-700 rounded-lg transition-colors"
>AGiXT Config</button><button
onClick={() =>setIsEditorOpen(true)}
className="px-4 py-2 bg-indigo-600 hover:bg-indigo-700 rounded-lg transition-colors"
>New Task</button></div></div>{isAGiXTConfigOpen && (<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50"><div className="bg-gray-800 p-6 rounded-lg w-full max-w-2xl mx-4"><AGiXTConfig
onClose={() =>setIsAGiXTConfigOpen(false)}
onSave={(config) =>{
setAgixtConfig(config);
setIsAGiXTConfigOpen(false);
}}
/></div></div>)}<SearchBar
searchTerm={searchTerm}
onSearchChange={setSearchTerm}
sortBy={sortBy}
onSortChange={setSortBy}
filterPriority={filterPriority}
onFilterChange={setFilterPriority}
/></header><WorkspacePanel /><div className="space-y-6 mb-8"><div className="grid grid-cols-1 md:grid-cols-2 gap-6"><TaskAnalytics tasks={tasks} /><TaskAutomation tasks={tasks} onUpdateTask={updateTask} /></div><TaskDependencyGraph
tasks={tasks}
onTaskClick={setSelectedTask}
/></div><DragDropContext onDragEnd={onDragEnd}><main className="grid grid-cols-1 md:grid-cols-3 gap-6"><div className="bg-gray-800 rounded-lg p-4"><h2 className="text-xl font-semibold mb-4">To Do</h2><TaskListComponent
droppableId="todo"
tasks={filteredAndSortedTasks().filter(task =>task.status === 'todo')}
onUpdateTask={updateTask}
onTaskClick={(task) =>setSelectedTask(task)}
onDeleteTask={(task) =>deleteTask(task.id)}
onReorderTasks={reorderTasks}
listId="default"
/></div><div className="bg-gray-800 rounded-lg p-4"><h2 className="text-xl font-semibold mb-4">In Progress</h2><TaskListComponent
droppableId="in-progress"
tasks={filteredAndSortedTasks().filter(task =>task.status === 'in-progress')}
onUpdateTask={updateTask}
onTaskClick={(task) =>setSelectedTask(task)}
onDeleteTask={(task) =>deleteTask(task.id)}
onReorderTasks={reorderTasks}
listId="default"
/></div><div className="bg-gray-800 rounded-lg p-4"><h2 className="text-xl font-semibold mb-4">Done</h2><TaskListComponent
droppableId="done"
tasks={filteredAndSortedTasks().filter(task =>task.status === 'done')}
onUpdateTask={updateTask}
onTaskClick={(task) =>setSelectedTask(task)}
onDeleteTask={(task) =>deleteTask(task.id)}
onReorderTasks={reorderTasks}
listId="default"
/></div></main></DragDropContext>{isEditorOpen && (<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50"><div className="bg-gray-800 p-6 rounded-lg w-full max-w-2xl mx-4"><TaskForm
onSubmit={(task) =>{
addTask(task);
setIsEditorOpen(false);
}}
onCancel={() =>setIsEditorOpen(false)}
lists={lists}
/></div></div>)}</div><div className="flex flex-col">{agixtConfig.backendUrl && agixtConfig.authToken && (<AIAssistantPanel
backendUrl={agixtConfig.backendUrl}
authToken={agixtConfig.authToken}
onTaskSuggestion={handleTaskSuggestion}
onTaskOptimization={handleTaskOptimization}
tasks={tasks}
selectedTask={selectedTask}
className="ml-4"
/>)}{selectedTask && (<TaskDetailsPanel
task={selectedTask}
onClose={() =>setSelectedTask(null)}
onUpdateTask={updateTask}
allTasks={tasks}
className="ml-4 mt-4"
/>)}</div></div></div></ThemeProvider>);
};

export default TaskPanel;
}

return (<ThemeProvider value={{ theme, setTheme }}><div className="min-h-screen bg-[#111111] text-white p-4"><div className="flex"><div className="flex-1 max-w-7xl mx-auto"><header className="mb-8"><div className="flex justify-between items-center mb-4"><h1 className="text-2xl font-bold">Task Panel</h1><div className="flex items-center space-x-4"><ThemeSelector currentTheme={theme} onThemeChange={setTheme} /><button
onClick={() =>setIsAGiXTConfigOpen(true)}
className="px-4 py-2 bg-gray-600 hover:bg-gray-700 rounded-lg transition-colors"
>AGiXT Config</button><button
onClick={() =>setIsEditorOpen(true)}
className="px-4 py-2 bg-indigo-600 hover:bg-indigo-700 rounded-lg transition-colors"
>New Task</button></div></div>{isAGiXTConfigOpen && (<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50"><div className="bg-gray-800 p-6 rounded-lg w-full max-w-2xl mx-4"><AGiXTConfig
onClose={() =>setIsAGiXTConfigOpen(false)}
onSave={(config) =>{
setAgixtConfig(config);
setIsAGiXTConfigOpen(false);
}}
/></div></div>)}<SearchBar
searchTerm={searchTerm}
onSearchChange={setSearchTerm}
sortBy={sortBy}
onSortChange={setSortBy}
filterPriority={filterPriority}
onFilterChange={setFilterPriority}
/></header><div className="space-y-6 mb-8"><div className="grid grid-cols-1 md:grid-cols-2 gap-6"><TaskAnalytics tasks={tasks} /><TaskAutomation tasks={tasks} onUpdateTask={updateTask} /></div><TaskDependencyGraph
tasks={tasks}
onTaskClick={setSelectedTask}
/></div><DragDropContext onDragEnd={onDragEnd}><main className="grid grid-cols-1 md:grid-cols-3 gap-6"><div className="bg-gray-800 rounded-lg p-4"><h2 className="text-xl font-semibold mb-4">To Do</h2><TaskListComponent
droppableId="todo"
tasks={filteredAndSortedTasks().filter(task =>task.status === 'todo')}
onUpdateTask={updateTask}
onTaskClick={(task) =>setSelectedTask(task)}
onDeleteTask={(task) =>deleteTask(task.id)}
onReorderTasks={reorderTasks}
listId="default"
/></div><div className="bg-gray-800 rounded-lg p-4"><h2 className="text-xl font-semibold mb-4">In Progress</h2><TaskListComponent
droppableId="in-progress"
tasks={filteredAndSortedTasks().filter(task =>task.status === 'in-progress')}
onUpdateTask={updateTask}
onTaskClick={(task) =>setSelectedTask(task)}
onDeleteTask={(task) =>deleteTask(task.id)}
onReorderTasks={reorderTasks}
listId="default"
/></div><div className="bg-gray-800 rounded-lg p-4"><h2 className="text-xl font-semibold mb-4">Done</h2><TaskListComponent
droppableId="done"
tasks={filteredAndSortedTasks().filter(task =>task.status === 'done')}
onUpdateTask={updateTask}
onTaskClick={(task) =>setSelectedTask(task)}
onDeleteTask={(task) =>deleteTask(task.id)}
onReorderTasks={reorderTasks}
listId="default"
/></div></main></DragDropContext>{isEditorOpen && (<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50"><div className="bg-gray-800 p-6 rounded-lg w-full max-w-2xl mx-4"><TaskForm
onSubmit={(task) =>{
addTask(task);
setIsEditorOpen(false);
}}
onCancel={() =>setIsEditorOpen(false)}
lists={lists}
/></div></div>)}</div><div className="flex flex-col">{agixtConfig.backendUrl && agixtConfig.authToken && (<AIAssistantPanel
backendUrl={agixtConfig.backendUrl}
authToken={agixtConfig.authToken}
onTaskSuggestion={handleTaskSuggestion}
onTaskOptimization={handleTaskOptimization}
tasks={tasks}
selectedTask={selectedTask}
className="ml-4"
/>)}
{selectedTask && (<TaskDetailsPanel
task={selectedTask}
onClose={() =>setSelectedTask(null)}
onUpdateTask={updateTask}
allTasks={tasks}
className="ml-4 mt-4"
/>)}</div></div></div></ThemeProvider>);
};

export default TaskPanel;
</div>
);
}
Expand Down

0 comments on commit 6ac11e0

Please sign in to comment.