ThatAIguyA world of ideas

THE CONSCIOUSNESS ATLAS
Read. Experiment. Follow the evidence.

ConsciousnessLearn · Explore · Joseph Anady

Janady13/llms-txt-hub / apps/web/hooks/use-load-more.ts

Source identity, revision, and recovered contents.

GitHub sourceSource text recovered

Source identity

FieldRecorded value
Source typeGitHub source
Original recordJanady13/llms-txt-hub / apps/web/hooks/use-load-more.ts
DateNot specified in source
RepositoryJanady13/llms-txt-hub
Revisione0f4bf978d4df168369c7601d9c5f5ea89e84377
Branchmain
Path or archive memberapps/web/hooks/use-load-more.ts
Original SHA-256e370498c1b5770d39bc01d7a8b44c89489500b4ded79b163c65703aec29576d9
Git blob SHA601408ef11a2dfa50009c97dd1f2fd6e10e293b4
Reading-copy SHA-256e370498c1b5770d39bc01d7a8b44c89489500b4ded79b163c65703aec29576d9

Original source ↗

Recovered source transcript

'use client' import { logger } from '@thedaviddias/logging' import { useCallback, useEffect, useMemo, useState } from 'react' // Traditional client-side pagination for static data interface UseLoadMoreProps<T> { items: T[] initialItemsPerPage?: number itemsPerLoad?: number } interface UseLoadMoreReturn<T> { displayedItems: T[] hasMore: boolean isLoading: boolean currentPage: number totalPages: number loadMore: () => Promise<void> reset: () => void showItemsCount: number totalItemsCount: number } // API-based pagination for dynamic data fetching interface UseApiLoadMoreProps { apiEndpoint: string initialPage?: number itemsPerPage?: number searchQuery?: string filter?: string } interface UseApiLoadMoreReturn<T> { items: T[] hasMore: boolean isLoading: boolean isLoadingMore: boolean currentPage: number totalPages: number totalCount: number error: string | null loadMore: () => Promise<void> reset: () => void refetch: () => Promise<void> } /** * Client-side pagination hook that slices a static array of items */ export function useLoadMore<T>({ items, initialItemsPerPage = 12, itemsPerLoad = 12 }: UseLoadMoreProps<T>): UseLoadMoreReturn<T> { const [currentPage, setCurrentPage] = useState(1) const [isLoading, setIsLoading] = useState(false) const totalPages = Math.ceil(items.length / itemsPerLoad) const showItemsCount = Math.min( initialItemsPerPage + (currentPage - 1) * itemsPerLoad, items.length ) const displayedItems = useMemo(() => { return items.slice(0, showItemsCount) }, [items, showItemsCount]) const hasMore = showItemsCount < items.length const loadMore = useCallback(async () => { if (!hasMore || isLoading) return setIsLoading(true) // Simulate network delay for better UX await new Promise(resolve => setTimeout(resolve, 300)) setCurrentPage(prev => prev + 1) setIsLoading(false) }, [hasMore, isLoading]) const reset = useCallback(() => { setCurrentPage(1) setIsLoading(false) }, []) return { displayedItems, hasMore, isLoading, currentPage, totalPages, loadMore, reset, showItemsCount, totalItemsCount: items.length } } /** * API-based pagination hook for progressive data loading */ export function useApiLoadMore<T>({ apiEndpoint, initialPage = 1, itemsPerPage = 12, searchQuery = '', filter = '' }: UseApiLoadMoreProps): UseApiLoadMoreReturn<T> { const [items, setItems] = useState<T[]>([]) const [currentPage, setCurrentPage] = useState(initialPage) const [totalPages, setTotalPages] = useState(0) const [totalCount, setTotalCount] = useState(0) const [hasMore, setHasMore] = useState(true) const [isLoading, setIsLoading] = useState(false) const [isLoadingMore, setIsLoadingMore] = useState(false) const [error, setError] = useState<string | null>(null) const [lastSearchQuery, setLastSearchQuery] = useState(searchQuery) const [lastFilter, setLastFilter] = useState(filter) // Build API URL with parameters const buildApiUrl = useCallback( (page: number, search?: string, filterValue?: string) => { const params = new URLSearchParams() params.set('page', page.toString()) params.set('limit', itemsPerPage.toString()) if (search?.trim()) { params.set('search', search.trim()) } if (filterValue?.trim()) { params.set('filter', filterValue.trim()) } return `${apiEndpoint}?${params.toString()}` }, [apiEndpoint, itemsPerPage] ) // Fetch data from API const fetchData = useCallback( async (page: number, isAppending = false, search?: string, filterValue?: string) => { try { if (isAppending) { setIsLoadingMore(true) } else { setIsLoading(true) setError(null) } const url = buildApiUrl(page, search, filterValue) const response = await fetch(url) if (!response.ok) { throw new Error(`Failed to fetch data: ${response.statusText}`) } const data = await response.json() if (data.error) { throw new Error(data.error) } const { members, pagination } = data if (isAppending) { setItems(prevItems => [...prevItems, ...members]) } else { setItems(members) } setTotalPages(pagination.totalPages) setTotalCount(pagination.total) setHasMore(pagination.hasMore) setCurrentPage(page) } catch (err) { const errorMessage = err instanceof Error ? err.message : 'An error occurred' setError(errorMessage) logger.error(err instanceof Error ? err : new Error(String(err)), { data: err, tags: { type: 'hook', hook: 'use-load-more' } }) } finally { setIsLoading(false) setIsLoadingMore(false) } }, [buildApiUrl] ) // Load more items (next page) const loadMore = useCallback(async () => { if (!hasMore || isLoadingMore || isLoading) return await fetchData(currentPage + 1, true, searchQuery, filter) }, [hasMore, isLoadingMore, isLoading, currentPage, fetchData, searchQuery, filter]) // Reset to first page const reset = useCallback(() => { setCurrentPage(1) setItems([]) setError(null) setHasMore(true) fetchData(1, false, searchQuery, filter) }, [fetchData, searchQuery, filter]) // Refetch current data const refetch = useCallback(async () => { await fetchData(1, false, searchQuery, filter) }, [fetchData, searchQuery, filter]) // Effect to handle search/filter changes useEffect(() => { const searchChanged = searchQuery !== lastSearchQuery const filterChanged = filter !== lastFilter if (searchChanged || filterChanged) { setLastSearchQuery(searchQuery) setLastFilter(filter) setCurrentPage(1) setItems([]) setError(null) setHasMore(true) fetchData(1, false, searchQuery, filter) } }, [searchQuery, filter, lastSearchQuery, lastFilter, fetchData]) // Initial data load useEffect(() => { if (items.length === 0 && !isLoading && !error) { fetchData(initialPage, false, searchQuery, filter) } }, [fetchData, initialPage, searchQuery, filter, items.length, isLoading, error]) return { items, hasMore, isLoading, isLoadingMore, currentPage, totalPages, totalCount, error, loadMore, reset, refetch } }

Search equations, builds, manuscript text, and recovered sources.