Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3533 | Rev 3603 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
3599 stevensc 1
import { useEffect, useState, useCallback, useMemo } from 'react';
3511 stevensc 2
 
3
import { useFetch } from './useFetch';
4
 
3530 stevensc 5
export function usePagination(
6
  url,
3599 stevensc 7
  {
8
    initialPage = 1,
9
    initialLimit = 10,
10
    initialParams = {},
11
    enableInfiniteScroll = false,
12
    resetOnUrlChange = true
13
  } = {}
3530 stevensc 14
) {
3529 stevensc 15
  const [items, setItems] = useState([]);
3511 stevensc 16
  const [page, setPage] = useState(initialPage);
3529 stevensc 17
  const [totalPages, setTotalPages] = useState(0);
3599 stevensc 18
  const [totalItems, setTotalItems] = useState(0);
3511 stevensc 19
  const [limit, setLimit] = useState(initialLimit);
3530 stevensc 20
  const [params, setParams] = useState({ page, limit, ...initialParams });
3511 stevensc 21
 
3529 stevensc 22
  const { data, loading, error, refetch } = useFetch(url, {
23
    params
24
  });
3511 stevensc 25
 
3599 stevensc 26
  // Memoized pagination state
27
  const paginationState = useMemo(
28
    () => ({
29
      page,
30
      limit,
31
      totalPages,
32
      totalItems,
33
      hasMore: page < totalPages,
34
      hasPrevious: page > 1,
35
      isFirstPage: page === 1,
36
      isLastPage: page === totalPages
37
    }),
38
    [page, limit, totalPages, totalItems]
39
  );
3511 stevensc 40
 
3599 stevensc 41
  // Optimized page navigation functions
42
  const nextPage = useCallback(() => {
43
    if (paginationState.hasMore) {
44
      setPage((prevPage) => prevPage + 1);
45
    }
46
  }, [paginationState.hasMore]);
3511 stevensc 47
 
3599 stevensc 48
  const prevPage = useCallback(() => {
49
    if (paginationState.hasPrevious) {
50
      setPage((prevPage) => prevPage - 1);
51
    }
52
  }, [paginationState.hasPrevious]);
3511 stevensc 53
 
3599 stevensc 54
  const goToPage = useCallback(
55
    (newPage) => {
56
      if (newPage >= 1 && newPage <= totalPages) {
57
        setPage(newPage);
58
      }
59
    },
60
    [totalPages]
61
  );
3511 stevensc 62
 
3599 stevensc 63
  const setPageLimit = useCallback((newLimit) => {
64
    if (newLimit > 0) {
65
      setLimit(newLimit);
66
      setPage(1);
67
    }
68
  }, []);
3511 stevensc 69
 
3599 stevensc 70
  const resetPagination = useCallback(() => {
71
    setPage(initialPage);
72
    setItems([]);
73
    setTotalPages(0);
74
    setTotalItems(0);
75
  }, [initialPage]);
76
 
77
  const updateParams = useCallback((newParams) => {
78
    setParams((prevParams) => ({ ...prevParams, ...newParams }));
79
  }, []);
80
 
81
  // Handle data updates with flexible structure support
3529 stevensc 82
  useEffect(() => {
83
    if (data) {
3599 stevensc 84
      let newItems = [];
85
      let pages = 0;
86
      let items = 0;
87
 
88
      // Handle different response structures
89
      if (data?.current?.items) {
90
        // Structure: { current: { items: [] }, total: { pages: number, items: number } }
91
        newItems = data.current.items;
92
        pages = data.total?.pages || 0;
93
        items = data.total?.items || 0;
94
      } else if (data?.data && Array.isArray(data.data)) {
95
        // Structure: { data: [], pagination: { ... } }
96
        newItems = data.data;
97
        pages = data.pagination?.pageCount || data.pagination?.last || 0;
98
        items = data.pagination?.totalItemCount || 0;
99
      } else if (Array.isArray(data)) {
100
        // Structure: direct array
101
        newItems = data;
102
        pages = 1;
103
        items = data.length;
104
      } else if (data?.items && Array.isArray(data.items)) {
105
        // Structure: { items: [], pagination: { ... } }
106
        newItems = data.items;
107
        pages = data.pagination?.pageCount || data.pagination?.last || 0;
108
        items = data.pagination?.totalItemCount || 0;
109
      }
110
 
111
      setItems((prevItems) => {
112
        if (enableInfiniteScroll && page > 1) {
113
          // For infinite scroll, append new items
114
          return [...prevItems, ...newItems];
115
        } else {
116
          // For regular pagination, replace items
117
          return newItems;
118
        }
119
      });
120
 
121
      setTotalPages(pages);
122
      setTotalItems(items);
3529 stevensc 123
    }
3599 stevensc 124
  }, [data, page, enableInfiniteScroll]);
3529 stevensc 125
 
3599 stevensc 126
  // Update params when page or limit changes
3529 stevensc 127
  useEffect(() => {
3599 stevensc 128
    setParams((prevParams) => ({
129
      ...prevParams,
130
      page,
131
      limit
132
    }));
3529 stevensc 133
  }, [page, limit]);
134
 
3599 stevensc 135
  // Reset pagination when URL changes (if enabled)
136
  useEffect(() => {
137
    if (resetOnUrlChange) {
138
      resetPagination();
139
    }
140
  }, [url, resetOnUrlChange, resetPagination]);
141
 
3511 stevensc 142
  return {
3599 stevensc 143
    // Data
3529 stevensc 144
    items,
3599 stevensc 145
    ...paginationState,
146
 
147
    // Loading and error states
148
    loading,
3529 stevensc 149
    error,
3599 stevensc 150
 
151
    // Actions
3511 stevensc 152
    nextPage,
153
    prevPage,
154
    goToPage,
155
    setPageLimit,
3599 stevensc 156
    resetPagination,
157
    updateParams,
3529 stevensc 158
    refetch
3511 stevensc 159
  };
160
}