- Ajout d'un système de recherche avec bouton "Rechercher" - Support de la validation par touche Entrée - Recherche côté serveur avec filtres MongoDB sur nom et email - Réinitialisation automatique de la page lors d'une nouvelle recherche - Suppression du debounce automatique pour un contrôle utilisateur total 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
74 lines
1.9 KiB
TypeScript
74 lines
1.9 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useEffect, useCallback, useMemo } from "react";
|
|
|
|
interface UseCollectionOptions {
|
|
page?: number;
|
|
limit?: number;
|
|
filter?: Record<string, unknown>;
|
|
search?: string;
|
|
}
|
|
|
|
interface CollectionResponse<T> {
|
|
data: T[];
|
|
total: number;
|
|
page: number;
|
|
limit: number;
|
|
totalPages: number;
|
|
}
|
|
|
|
export function useCollection<T = Record<string, unknown>>(
|
|
collectionName: string,
|
|
options: UseCollectionOptions = {}
|
|
) {
|
|
const [data, setData] = useState<T[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [total, setTotal] = useState(0);
|
|
const [totalPages, setTotalPages] = useState(0);
|
|
|
|
const { page = 1, limit = 20, filter = {}, search } = options;
|
|
|
|
// Mémoriser la chaîne JSON du filtre pour éviter les re-renders inutiles
|
|
const filterString = useMemo(() => JSON.stringify(filter), [filter]);
|
|
|
|
const fetchData = useCallback(async () => {
|
|
try {
|
|
setLoading(true);
|
|
const params = new URLSearchParams({
|
|
page: page.toString(),
|
|
limit: limit.toString(),
|
|
filter: filterString,
|
|
});
|
|
if (search) {
|
|
params.append("search", search);
|
|
}
|
|
|
|
const response = await fetch(
|
|
`/api/collections/${collectionName}?${params}`
|
|
);
|
|
if (!response.ok)
|
|
throw new Error(`Erreur lors du chargement de ${collectionName}`);
|
|
|
|
const result: CollectionResponse<T> = await response.json();
|
|
setData(result.data);
|
|
setTotal(result.total);
|
|
setTotalPages(result.totalPages);
|
|
} catch (err) {
|
|
setError(err instanceof Error ? err.message : "Erreur inconnue");
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, [collectionName, page, limit, filterString, search]);
|
|
|
|
useEffect(() => {
|
|
fetchData();
|
|
}, [fetchData]);
|
|
|
|
const refetch = useCallback(() => {
|
|
return fetchData();
|
|
}, [fetchData]);
|
|
|
|
return { data, loading, error, total, totalPages, refetch };
|
|
}
|