Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3599 | Rev 3604 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

import { useEffect, useState, useCallback, useMemo } from 'react';

import { useFetch } from './useFetch';

/* const paginationResponseExample = {
  success: true,
  data: [
    {
      uuid: 'b18afb55-d40e-4fd9-95a6-324a7f45e57f',
      sender_name: 'Cesa Managment Solution',
      sender_image:
        'https://dev-services.leaderslinked.com/storage/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      sender_profile: '/profile/view/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      receiver_name: 'Santiago Olivera',
      receiver_image:
        'https://dev-services.leaderslinked.com/storage/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      receiver_profile: '/profile/view/e85129fa-18eb-4149-8640-fea9ae916cdc',
      side: 'right',
      message: '',
      type: 'image',
      filename:
        'https://dev-services.leaderslinked.com/storage/b18afb55-d40e-4fd9-95a6-324a7f45e57f',
      date: 'hace 1 año',
      url_abuse_report:
        'https://dev-services.leaderslinked.com/helpers/abuse-report/message/b18afb55-d40e-4fd9-95a6-324a7f45e57f'
    },
    {
      uuid: 'c3b3c887-9f88-4a36-a7c8-c417f5da80ff',
      sender_name: 'Cesa Managment Solution',
      sender_image:
        'https://dev-services.leaderslinked.com/storage/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      sender_profile: '/profile/view/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      receiver_name: 'Santiago Olivera',
      receiver_image:
        'https://dev-services.leaderslinked.com/storage/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      receiver_profile: '/profile/view/e85129fa-18eb-4149-8640-fea9ae916cdc',
      side: 'right',
      message: 'Buenas tardes',
      type: 'text',
      filename: '',
      date: 'hace 1 año',
      url_abuse_report:
        'https://dev-services.leaderslinked.com/helpers/abuse-report/message/c3b3c887-9f88-4a36-a7c8-c417f5da80ff'
    },
    {
      uuid: '59120c84-335f-424c-8990-db51ae7bd673',
      sender_name: 'Santiago Olivera',
      sender_image:
        'https://dev-services.leaderslinked.com/storage/e85129fa-18eb-4149-8640-fea9ae916cdc',
      sender_profile: '/profile/view/e85129fa-18eb-4149-8640-fea9ae916cdc',
      receiver_name: 'Cesa Managment Solution',
      receiver_image:
        'https://dev-services.leaderslinked.com/storage/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      receiver_profile: '/profile/view/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      side: 'left',
      message: '',
      type: 'image',
      filename:
        'https://dev-services.leaderslinked.com/storage/59120c84-335f-424c-8990-db51ae7bd673',
      date: 'hace 1 año',
      url_abuse_report: ''
    },
    {
      uuid: '71c1356d-b5dc-413a-8f8e-ed087f99b6e3',
      sender_name: 'Santiago Olivera',
      sender_image:
        'https://dev-services.leaderslinked.com/storage/e85129fa-18eb-4149-8640-fea9ae916cdc',
      sender_profile: '/profile/view/e85129fa-18eb-4149-8640-fea9ae916cdc',
      receiver_name: 'Cesa Managment Solution',
      receiver_image:
        'https://dev-services.leaderslinked.com/storage/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      receiver_profile: '/profile/view/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      side: 'left',
      message: 'buenas tardes',
      type: 'text',
      filename: '',
      date: 'hace 1 año',
      url_abuse_report: ''
    },
    {
      uuid: 'c484b564-3d69-42bf-b6c4-12dfa6230614',
      sender_name: 'Santiago Olivera',
      sender_image:
        'https://dev-services.leaderslinked.com/storage/e85129fa-18eb-4149-8640-fea9ae916cdc',
      sender_profile: '/profile/view/e85129fa-18eb-4149-8640-fea9ae916cdc',
      receiver_name: 'Cesa Managment Solution',
      receiver_image:
        'https://dev-services.leaderslinked.com/storage/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      receiver_profile: '/profile/view/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      side: 'left',
      message: 'Test',
      type: 'text',
      filename: '',
      date: 'hace 1 año',
      url_abuse_report: ''
    },
    {
      uuid: 'f29723fd-dc2a-4b06-8c8e-e0e0cfe36cd1',
      sender_name: 'Cesa Managment Solution',
      sender_image:
        'https://dev-services.leaderslinked.com/storage/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      sender_profile: '/profile/view/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      receiver_name: 'Santiago Olivera',
      receiver_image:
        'https://dev-services.leaderslinked.com/storage/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      receiver_profile: '/profile/view/e85129fa-18eb-4149-8640-fea9ae916cdc',
      side: 'right',
      message:
        'buenas tardes\r\n\r\nbuenas tardesbuenas tardes\r\n\r\nbuenas tardesbuenas tardes\r\n\r\nbuenas tardesbuenas tardesbuenas tardes',
      type: 'document',
      filename:
        'https://dev-services.leaderslinked.com/storage/f29723fd-dc2a-4b06-8c8e-e0e0cfe36cd1',
      date: 'hace 1 año',
      url_abuse_report:
        'https://dev-services.leaderslinked.com/helpers/abuse-report/message/f29723fd-dc2a-4b06-8c8e-e0e0cfe36cd1'
    },
    {
      uuid: '86453fcf-ac3b-4228-9007-9dbf100976ef',
      sender_name: 'Cesa Managment Solution',
      sender_image:
        'https://dev-services.leaderslinked.com/storage/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      sender_profile: '/profile/view/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      receiver_name: 'Santiago Olivera',
      receiver_image:
        'https://dev-services.leaderslinked.com/storage/97e43a0a-5a85-4021-8bff-167d60e2a0f2',
      receiver_profile: '/profile/view/e85129fa-18eb-4149-8640-fea9ae916cdc',
      side: 'right',
      message:
        'hola,hola,hola,hola,hola,hola,hola,\r\nhola,hola,hola,\r\n\r\nhola,hola,\r\nhola,hola,hola,\r\n\r\nhola,hola,hola,',
      type: 'image',
      filename:
        'https://dev-services.leaderslinked.com/storage/86453fcf-ac3b-4228-9007-9dbf100976ef',
      date: 'hace 1 año',
      url_abuse_report:
        'https://dev-services.leaderslinked.com/helpers/abuse-report/message/86453fcf-ac3b-4228-9007-9dbf100976ef'
    }
  ],
  pagination: {
    pageCount: 1,
    itemCountPerPage: 10,
    first: 1,
    current: 1,
    last: 1,
    pagesInRange: {
      1: 1
    },
    firstPageInRange: 1,
    lastPageInRange: 1,
    currentItemCount: 7,
    totalItemCount: 7,
    firstItemNumber: 1,
    lastItemNumber: 7
  }
}; */

/**
 * Hook optimizado para infinite scroll
 * Maneja la paginación automática al hacer scroll
 */
export function usePagination(
  url,
  {
    initialPage = 1,
    initialLimit = 20,
    initialParams = {},
    resetOnUrlChange = true,
    autoLoadFirstPage = true
  } = {}
) {
  const [items, setItems] = useState([]);
  const [page, setPage] = useState(initialPage);
  const [totalPages, setTotalPages] = useState(0);
  const [totalItems, setTotalItems] = useState(0);
  const [limit, setLimit] = useState(initialLimit);
  const [params, setParams] = useState({ page, limit, ...initialParams });

  const { data, loading, error, refetch } = useFetch(url, {
    params
  });

  // Memoized pagination state for infinite scroll
  const paginationState = useMemo(
    () => ({
      page,
      limit,
      totalPages,
      totalItems,
      hasMore: page < totalPages,
      isLoading: loading,
      error
    }),
    [page, limit, totalPages, totalItems, loading, error]
  );

  // Load next page for infinite scroll
  const nextPage = useCallback(() => {
    if (paginationState.hasMore && !loading) {
      setPage((prevPage) => prevPage + 1);
    }
  }, [paginationState.hasMore, loading]);

  // Reset pagination when URL changes
  const resetPagination = useCallback(() => {
    setPage(initialPage);
    setItems([]);
    setTotalPages(0);
    setTotalItems(0);
  }, [initialPage]);

  // Update params when page or limit changes
  useEffect(() => {
    setParams((prevParams) => ({
      ...prevParams,
      page,
      limit
    }));
  }, [page, limit]);

  // Reset pagination when URL changes (if enabled)
  useEffect(() => {
    if (resetOnUrlChange && url) {
      resetPagination();
    }
  }, [url, resetOnUrlChange, resetPagination]);

  // Handle data updates with infinite scroll logic
  useEffect(() => {
    if (data) {
      let newItems = [];
      let pages = 0;
      let items = 0;

      // Handle different response structures
      if (data?.current?.items) {
        // Structure: { current: { items: [] }, total: { pages, items } }
        newItems = data.current.items;
        pages = data.total?.pages || 0;
        items = data.total?.items || 0;
      } else if (data?.data && Array.isArray(data.data)) {
        // Structure: { data: [], pagination: { ... } }
        newItems = data.data;
        pages = data.pagination?.pageCount || data.pagination?.last || 0;
        items = data.pagination?.totalItemCount || 0;
      } else if (Array.isArray(data)) {
        // Structure: direct array
        newItems = data;
        pages = 1;
        items = data.length;
      } else if (data?.items && Array.isArray(data.items)) {
        // Structure: { items: [], pagination: { ... } }
        newItems = data.items;
        pages = data.pagination?.pageCount || data.pagination?.last || 0;
        items = data.pagination?.totalItemCount || 0;
      }

      setItems((prevItems) => {
        // For infinite scroll, always append new items
        if (page > 1) {
          return [...prevItems, ...newItems];
        } else {
          // First page, replace items
          return newItems;
        }
      });

      setTotalPages(pages);
      setTotalItems(items);
    }
  }, [data, page]);

  // Auto-load first page if enabled and URL is provided
  useEffect(() => {
    if (autoLoadFirstPage && url && page === 1 && items.length === 0) {
      // The useFetch hook will automatically load the data
    }
  }, [url, autoLoadFirstPage, page, items.length]);

  return {
    // Data
    items,
    ...paginationState,

    // Actions
    nextPage,
    resetPagination,
    refetch
  };
}