feat: adding status archived and refacto type in one place only

This commit is contained in:
Julien Froidefond
2025-09-15 10:24:49 +02:00
parent 05cd099cf4
commit 363e739b5c
7 changed files with 42 additions and 52 deletions

View File

@@ -1,5 +1,5 @@
import { httpClient } from './base/http-client';
import { Task, TaskStatus, TaskPriority } from '@/lib/types';
import { Task, TaskStatus, TaskPriority, TaskStats } from '@/lib/types';
export interface TaskFilters {
status?: TaskStatus[];
@@ -12,15 +12,7 @@ export interface TaskFilters {
export interface TasksResponse {
success: boolean;
data: Task[];
stats: {
total: number;
completed: number;
inProgress: number;
todo: number;
cancelled: number;
freeze: number;
completionRate: number;
};
stats: TaskStats;
count: number;
}

View File

@@ -3,19 +3,11 @@
import { KanbanBoardContainer } from '@/components/kanban/BoardContainer';
import { Header } from '@/components/ui/Header';
import { TasksProvider, useTasksContext } from '@/contexts/TasksContext';
import { Task, Tag } from '@/lib/types';
import { Task, Tag, TaskStats } from '@/lib/types';
interface HomePageClientProps {
initialTasks: Task[];
initialStats: {
total: number;
completed: number;
inProgress: number;
todo: number;
cancelled: number;
freeze: number;
completionRate: number;
};
initialStats: TaskStats;
initialTags: (Tag & { usage: number })[];
}

View File

@@ -1,18 +1,11 @@
import { Card, CardContent } from '@/components/ui/Card';
import { TaskStats } from '@/lib/types';
import Link from 'next/link';
interface HeaderProps {
title: string;
subtitle: string;
stats: {
total: number;
completed: number;
inProgress: number;
todo: number;
cancelled: number;
freeze: number;
completionRate: number;
};
stats: TaskStats;
syncing?: boolean;
}
@@ -98,6 +91,13 @@ export function Header({ title, subtitle, stats, syncing = false }: HeaderProps)
color="gray"
/>
)}
{stats.archived > 0 && (
<StatCard
label="ARCHIVE"
value={String(stats.archived).padStart(2, '0')}
color="gray"
/>
)}
<StatCard
label="RATE"
value={`${stats.completionRate}%`}

View File

@@ -2,19 +2,11 @@
import { useState, useEffect, useCallback } from 'react';
import { tasksClient, TaskFilters, CreateTaskData, UpdateTaskData } from '@/clients/tasks-client';
import { Task } from '@/lib/types';
import { Task, TaskStats } from '@/lib/types';
interface UseTasksState {
tasks: Task[];
stats: {
total: number;
completed: number;
inProgress: number;
todo: number;
cancelled: number;
freeze: number;
completionRate: number;
};
stats: TaskStats;
loading: boolean;
error: string | null;
syncing: boolean; // Pour indiquer les opérations optimistes en cours
@@ -34,7 +26,7 @@ interface UseTasksActions {
*/
export function useTasks(
initialFilters?: TaskFilters,
initialData?: { tasks: Task[]; stats: UseTasksState['stats'] }
initialData?: { tasks: Task[]; stats: TaskStats }
): UseTasksState & UseTasksActions {
const [state, setState] = useState<UseTasksState>({
tasks: initialData?.tasks || [],
@@ -45,6 +37,7 @@ export function useTasks(
todo: 0,
cancelled: 0,
freeze: 0,
archived: 0,
completionRate: 0
},
loading: false,
@@ -153,6 +146,7 @@ export function useTasks(
todo: updatedTasks.filter(t => t.status === 'todo').length,
cancelled: updatedTasks.filter(t => t.status === 'cancelled').length,
freeze: updatedTasks.filter(t => t.status === 'freeze').length,
archived: updatedTasks.filter(t => t.status === 'archived').length,
completionRate: updatedTasks.length > 0
? Math.round((updatedTasks.filter(t => t.status === 'done').length / updatedTasks.length) * 100)
: 0
@@ -196,6 +190,7 @@ export function useTasks(
todo: currentTasks.filter(t => t.status === 'todo').length,
cancelled: currentTasks.filter(t => t.status === 'cancelled').length,
freeze: currentTasks.filter(t => t.status === 'freeze').length,
archived: currentTasks.filter(t => t.status === 'archived').length,
completionRate: currentTasks.length > 0
? Math.round((currentTasks.filter(t => t.status === 'done').length / currentTasks.length) * 100)
: 0

View File

@@ -43,6 +43,13 @@ export const STATUS_CONFIG: Record<TaskStatus, StatusConfig> = {
icon: '✕',
color: 'red',
order: 5
},
archived: {
key: 'archived',
label: 'Archivé',
icon: '📦',
color: 'gray',
order: 6
}
} as const;

View File

@@ -1,9 +1,21 @@
// Types de base pour les tâches
// Note: TaskStatus et TaskPriority sont maintenant gérés par la configuration centralisée dans lib/status-config.ts
export type TaskStatus = 'todo' | 'in_progress' | 'done' | 'cancelled' | 'freeze';
export type TaskStatus = 'todo' | 'in_progress' | 'done' | 'cancelled' | 'freeze' | 'archived';
export type TaskPriority = 'low' | 'medium' | 'high' | 'urgent';
export type TaskSource = 'reminders' | 'jira' | 'manual';
// Interface centralisée pour les statistiques
export interface TaskStats {
total: number;
completed: number;
inProgress: number;
todo: number;
cancelled: number;
freeze: number;
archived: number;
completionRate: number;
}
// Interface principale pour les tâches
export interface Task {
id: string;

View File

@@ -4,7 +4,7 @@ import { createContext, useContext, ReactNode, useState, useMemo, useEffect } fr
import { useTasks } from '@/hooks/useTasks';
import { useTags } from '@/hooks/useTags';
import { userPreferencesService } from '@/services/user-preferences';
import { Task, Tag } from '@/lib/types';
import { Task, Tag, TaskStats } from '@/lib/types';
import { CreateTaskData, UpdateTaskData, TaskFilters } from '@/clients/tasks-client';
import { KanbanFilters } from '@/components/kanban/KanbanFilters';
import { sortTasks, getSortOption, DEFAULT_SORT, createSortKey } from '@/lib/sort-config';
@@ -12,15 +12,7 @@ import { sortTasks, getSortOption, DEFAULT_SORT, createSortKey } from '@/lib/sor
interface TasksContextType {
tasks: Task[]; // Toutes les tâches
regularTasks: Task[]; // Tâches sans les épinglées (pour Kanban)
stats: {
total: number;
completed: number;
inProgress: number;
todo: number;
cancelled: number;
freeze: number;
completionRate: number;
};
stats: TaskStats;
loading: boolean;
syncing: boolean;
error: string | null;
@@ -46,7 +38,7 @@ const TasksContext = createContext<TasksContextType | null>(null);
interface TasksProviderProps {
children: ReactNode;
initialTasks: Task[];
initialStats: TasksContextType['stats'];
initialStats: TaskStats;
initialTags?: (Tag & { usage: number })[];
}