refacto: passing by server actions on taskCard

This commit is contained in:
Julien Froidefond
2025-09-18 09:37:46 +02:00
parent 228e1563c6
commit 4a4eb9c8ad
15 changed files with 286 additions and 330 deletions

View File

@@ -1,8 +1,9 @@
'use client';
import { useState, useEffect, useCallback } from 'react';
import { tasksClient, TaskFilters, CreateTaskData, UpdateTaskData } from '@/clients/tasks-client';
import { Task, TaskStats } from '@/lib/types';
import { tasksClient, TaskFilters, CreateTaskData } from '@/clients/tasks-client';
import { updateTaskStatus } from '@/actions/tasks';
import { Task, TaskStats, TaskStatus } from '@/lib/types';
interface UseTasksState {
tasks: Task[];
@@ -15,9 +16,7 @@ interface UseTasksState {
interface UseTasksActions {
refreshTasks: () => Promise<void>;
createTask: (data: CreateTaskData) => Promise<Task | null>;
updateTask: (data: UpdateTaskData) => Promise<Task | null>;
updateTaskOptimistic: (data: UpdateTaskData) => Promise<Task | null>;
deleteTask: (taskId: string) => Promise<void>;
updateTaskOptimistic: (taskId: string, status: TaskStatus) => Promise<Task | null>;
setFilters: (filters: TaskFilters) => void;
}
@@ -95,35 +94,13 @@ export function useTasks(
}
}, [refreshTasks]);
/**
* Met à jour une tâche
*/
const updateTask = useCallback(async (data: UpdateTaskData): Promise<Task | null> => {
setState(prev => ({ ...prev, loading: true, error: null }));
try {
const response = await tasksClient.updateTask(data);
// Rafraîchir la liste après mise à jour
await refreshTasks();
return response.data;
} catch (error) {
setState(prev => ({
...prev,
loading: false,
error: error instanceof Error ? error.message : 'Erreur lors de la mise à jour'
}));
return null;
}
}, [refreshTasks]);
// Note: updateTask et deleteTask ont été migrés vers Server Actions
// Voir /src/actions/tasks.ts pour updateTaskTitle, updateTaskStatus, deleteTask
/**
* Met à jour une tâche de manière optimiste (pour drag & drop)
* Met à jour le statut d'une tâche de manière optimiste (pour drag & drop)
*/
const updateTaskOptimistic = useCallback(async (data: UpdateTaskData): Promise<Task | null> => {
const { taskId, ...updates } = data;
const updateTaskOptimistic = useCallback(async (taskId: string, status: TaskStatus): Promise<Task | null> => {
// 1. Sauvegarder l'état actuel pour rollback
const currentTasks = state.tasks;
const taskToUpdate = currentTasks.find(t => t.id === taskId);
@@ -134,7 +111,7 @@ export function useTasks(
}
// 2. Mise à jour optimiste immédiate de l'état local
const updatedTask = { ...taskToUpdate, ...updates };
const updatedTask = { ...taskToUpdate, status };
const updatedTasks = currentTasks.map(task =>
task.id === taskId ? updatedTask : task
);
@@ -162,24 +139,17 @@ export function useTasks(
syncing: true // Indiquer qu'une synchronisation est en cours
}));
// 3. Appel API en arrière-plan
// 3. Appel Server Action en arrière-plan
try {
const response = await tasksClient.updateTask(data);
const result = await updateTaskStatus(taskId, status);
// Si l'API retourne des données différentes, on met à jour
if (response.data) {
setState(prev => ({
...prev,
tasks: prev.tasks.map(task =>
task.id === taskId ? response.data : task
),
syncing: false // Synchronisation terminée
}));
} else {
// Si l'action réussit, la revalidation automatique se charge du reste
if (result.success) {
setState(prev => ({ ...prev, syncing: false }));
return result.data as Task;
} else {
throw new Error(result.error || 'Erreur lors de la mise à jour');
}
return response.data;
} catch (error) {
// 4. Rollback en cas d'erreur
setState(prev => ({
@@ -207,26 +177,8 @@ export function useTasks(
}
}, [state.tasks]);
/**
* Supprime une tâche
*/
const deleteTask = useCallback(async (taskId: string): Promise<void> => {
setState(prev => ({ ...prev, loading: true, error: null }));
try {
await tasksClient.deleteTask(taskId);
// Rafraîchir la liste après suppression
await refreshTasks();
} catch (error) {
setState(prev => ({
...prev,
loading: false,
error: error instanceof Error ? error.message : 'Erreur lors de la suppression'
}));
throw error; // Re-throw pour que l'UI puisse gérer l'erreur
}
}, [refreshTasks]);
// Note: deleteTask a été migré vers Server Actions
// Utilisez directement deleteTask depuis /src/actions/tasks.ts dans les composants
// Charger les tâches au montage seulement si pas de données initiales
useEffect(() => {
@@ -239,9 +191,7 @@ export function useTasks(
...state,
refreshTasks,
createTask,
updateTask,
updateTaskOptimistic,
deleteTask,
setFilters
};
}