feat: adding status archived and refacto type in one place only
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 })[];
|
||||
}
|
||||
|
||||
|
||||
@@ -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}%`}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
14
lib/types.ts
14
lib/types.ts
@@ -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;
|
||||
|
||||
@@ -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 })[];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user