refactor: simplify BoardContainer and update task management
- Removed initialTasks and initialStats props from KanbanBoardContainer, now using TasksContext for task management. - Updated useTasks hook to include a simulated delay for sync indicator during task updates. - Replaced KanbanBoardContainer with HomePageClient in the HomePage component for a cleaner structure.
This commit is contained in:
44
components/HomePageClient.tsx
Normal file
44
components/HomePageClient.tsx
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { KanbanBoardContainer } from '@/components/kanban/BoardContainer';
|
||||||
|
import { Header } from '@/components/ui/Header';
|
||||||
|
import { TasksProvider, useTasksContext } from '@/contexts/TasksContext';
|
||||||
|
import { Task } from '@/lib/types';
|
||||||
|
|
||||||
|
interface HomePageClientProps {
|
||||||
|
initialTasks: Task[];
|
||||||
|
initialStats: {
|
||||||
|
total: number;
|
||||||
|
completed: number;
|
||||||
|
inProgress: number;
|
||||||
|
todo: number;
|
||||||
|
completionRate: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function HomePageContent() {
|
||||||
|
const { stats, syncing } = useTasksContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-slate-950">
|
||||||
|
<Header
|
||||||
|
title="TowerControl"
|
||||||
|
subtitle="Gestionnaire de tâches moderne"
|
||||||
|
stats={stats}
|
||||||
|
syncing={syncing}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<main className="h-[calc(100vh-120px)]">
|
||||||
|
<KanbanBoardContainer />
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function HomePageClient({ initialTasks, initialStats }: HomePageClientProps) {
|
||||||
|
return (
|
||||||
|
<TasksProvider initialTasks={initialTasks} initialStats={initialStats}>
|
||||||
|
<HomePageContent />
|
||||||
|
</TasksProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -3,26 +3,12 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { KanbanBoard } from './Board';
|
import { KanbanBoard } from './Board';
|
||||||
import { EditTaskForm } from '@/components/forms/EditTaskForm';
|
import { EditTaskForm } from '@/components/forms/EditTaskForm';
|
||||||
import { useTasks } from '@/hooks/useTasks';
|
import { useTasksContext } from '@/contexts/TasksContext';
|
||||||
import { Task, TaskStatus } from '@/lib/types';
|
import { Task, TaskStatus } from '@/lib/types';
|
||||||
import { UpdateTaskData } from '@/clients/tasks-client';
|
import { UpdateTaskData } from '@/clients/tasks-client';
|
||||||
|
|
||||||
interface BoardContainerProps {
|
export function KanbanBoardContainer() {
|
||||||
initialTasks: Task[];
|
const { tasks, loading, createTask, deleteTask, updateTask, updateTaskOptimistic } = useTasksContext();
|
||||||
initialStats: {
|
|
||||||
total: number;
|
|
||||||
completed: number;
|
|
||||||
inProgress: number;
|
|
||||||
todo: number;
|
|
||||||
completionRate: number;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function KanbanBoardContainer({ initialTasks, initialStats }: BoardContainerProps) {
|
|
||||||
const { tasks, loading, syncing, createTask, deleteTask, updateTask, updateTaskOptimistic } = useTasks(
|
|
||||||
{ limit: 20 },
|
|
||||||
{ tasks: initialTasks, stats: initialStats }
|
|
||||||
);
|
|
||||||
|
|
||||||
const [editingTask, setEditingTask] = useState<Task | null>(null);
|
const [editingTask, setEditingTask] = useState<Task | null>(null);
|
||||||
|
|
||||||
|
|||||||
@@ -162,6 +162,9 @@ export function useTasks(
|
|||||||
|
|
||||||
// 3. Appel API en arrière-plan
|
// 3. Appel API en arrière-plan
|
||||||
try {
|
try {
|
||||||
|
// Délai artificiel pour voir l'indicateur de sync (à supprimer en prod)
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
|
|
||||||
const response = await tasksClient.updateTask(data);
|
const response = await tasksClient.updateTask(data);
|
||||||
|
|
||||||
// Si l'API retourne des données différentes, on met à jour
|
// Si l'API retourne des données différentes, on met à jour
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { tasksService } from '@/services/tasks';
|
import { tasksService } from '@/services/tasks';
|
||||||
import { KanbanBoardContainer } from '@/components/kanban/BoardContainer';
|
import { HomePageClient } from '@/components/HomePageClient';
|
||||||
import { HeaderContainer } from '@/components/ui/HeaderContainer';
|
|
||||||
|
|
||||||
export default async function HomePage() {
|
export default async function HomePage() {
|
||||||
// SSR - Récupération des données côté serveur
|
// SSR - Récupération des données côté serveur
|
||||||
@@ -10,19 +9,9 @@ export default async function HomePage() {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-slate-950">
|
<HomePageClient
|
||||||
<HeaderContainer
|
initialTasks={initialTasks}
|
||||||
title="TowerControl"
|
initialStats={initialStats}
|
||||||
subtitle="Gestionnaire de tâches moderne"
|
/>
|
||||||
initialStats={initialStats}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<main className="h-[calc(100vh-120px)]">
|
|
||||||
<KanbanBoardContainer
|
|
||||||
initialTasks={initialTasks}
|
|
||||||
initialStats={initialStats}
|
|
||||||
/>
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
55
src/contexts/TasksContext.tsx
Normal file
55
src/contexts/TasksContext.tsx
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { createContext, useContext, ReactNode } from 'react';
|
||||||
|
import { useTasks } from '@/hooks/useTasks';
|
||||||
|
import { Task } from '@/lib/types';
|
||||||
|
import { CreateTaskData, UpdateTaskData, TaskFilters } from '@/clients/tasks-client';
|
||||||
|
|
||||||
|
interface TasksContextType {
|
||||||
|
tasks: Task[];
|
||||||
|
stats: {
|
||||||
|
total: number;
|
||||||
|
completed: number;
|
||||||
|
inProgress: number;
|
||||||
|
todo: number;
|
||||||
|
completionRate: number;
|
||||||
|
};
|
||||||
|
loading: boolean;
|
||||||
|
syncing: boolean;
|
||||||
|
error: string | null;
|
||||||
|
createTask: (data: CreateTaskData) => Promise<Task | null>;
|
||||||
|
updateTask: (data: UpdateTaskData) => Promise<Task | null>;
|
||||||
|
updateTaskOptimistic: (data: UpdateTaskData) => Promise<Task | null>;
|
||||||
|
deleteTask: (taskId: string) => Promise<void>;
|
||||||
|
refreshTasks: () => Promise<void>;
|
||||||
|
setFilters: (filters: TaskFilters) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TasksContext = createContext<TasksContextType | null>(null);
|
||||||
|
|
||||||
|
interface TasksProviderProps {
|
||||||
|
children: ReactNode;
|
||||||
|
initialTasks: Task[];
|
||||||
|
initialStats: TasksContextType['stats'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TasksProvider({ children, initialTasks, initialStats }: TasksProviderProps) {
|
||||||
|
const tasksState = useTasks(
|
||||||
|
{ limit: 20 },
|
||||||
|
{ tasks: initialTasks, stats: initialStats }
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TasksContext.Provider value={tasksState}>
|
||||||
|
{children}
|
||||||
|
</TasksContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useTasksContext() {
|
||||||
|
const context = useContext(TasksContext);
|
||||||
|
if (!context) {
|
||||||
|
throw new Error('useTasksContext must be used within a TasksProvider');
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user