refactor: managements pages simplification

This commit is contained in:
Julien Froidefond
2025-08-23 07:50:25 +02:00
parent 5848f1331c
commit 2877e3b58f
7 changed files with 607 additions and 651 deletions

89
hooks/use-tree-view.ts Normal file
View File

@@ -0,0 +1,89 @@
import { useState, useEffect, useMemo, useCallback } from "react";
interface UseTreeViewOptions<T> {
data: T[];
searchFields: (keyof T)[];
groupBy: (item: T) => string;
searchTerm: string;
onSearchChange: (term: string) => void;
}
export function useTreeView<T>({
data,
searchFields,
groupBy,
searchTerm,
onSearchChange,
}: UseTreeViewOptions<T>) {
// État pour les catégories ouvertes/fermées
const [expandedCategories, setExpandedCategories] = useState<Set<string>>(new Set());
// Grouper les données par catégorie et filtrer en fonction de la recherche
const filteredDataByCategory = useMemo(() => {
// Grouper les données par catégorie
const dataByCategory = data.reduce((acc, item) => {
const categoryKey = groupBy(item);
if (!acc[categoryKey]) {
acc[categoryKey] = [];
}
acc[categoryKey].push(item);
return acc;
}, {} as Record<string, T[]>);
// Filtrer les données en fonction de la recherche
return Object.entries(dataByCategory).reduce((acc, [category, categoryItems]) => {
const filteredItems = categoryItems.filter((item) => {
const matchesSearch = searchFields.some((field) => {
const value = item[field];
if (typeof value === 'string') {
return value.toLowerCase().includes(searchTerm.toLowerCase());
}
return false;
});
return matchesSearch;
});
if (filteredItems.length > 0) {
acc[category] = filteredItems;
}
return acc;
}, {} as Record<string, T[]>);
}, [data, searchFields, groupBy, searchTerm]);
// Fonctions pour gérer l'expansion des catégories
const toggleCategory = useCallback((category: string) => {
setExpandedCategories((prev) => {
const newExpanded = new Set(prev);
if (newExpanded.has(category)) {
newExpanded.delete(category);
} else {
newExpanded.add(category);
}
return newExpanded;
});
}, []);
const expandAll = useCallback(() => {
setExpandedCategories(new Set(Object.keys(filteredDataByCategory)));
}, [filteredDataByCategory]);
const collapseAll = useCallback(() => {
setExpandedCategories(new Set());
}, []);
// Ouvrir automatiquement les catégories qui contiennent des résultats lors de la recherche
useEffect(() => {
if (searchTerm.trim()) {
const categoriesWithResults = Object.keys(filteredDataByCategory);
setExpandedCategories(new Set(categoriesWithResults));
}
}, [searchTerm, filteredDataByCategory]);
return {
filteredDataByCategory,
expandedCategories,
toggleCategory,
expandAll,
collapseAll,
};
}