mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 03:31:13 -05:00
Refactor code structure and remove redundant changes
This commit is contained in:
250
src-old/hooks/moderation/usePagination.ts
Normal file
250
src-old/hooks/moderation/usePagination.ts
Normal file
@@ -0,0 +1,250 @@
|
||||
/**
|
||||
* Pagination Hook
|
||||
*
|
||||
* Manages pagination state and actions for the moderation queue.
|
||||
*/
|
||||
|
||||
import { useState, useCallback, useEffect, useMemo } from 'react';
|
||||
import { MODERATION_CONSTANTS } from '@/lib/moderation/constants';
|
||||
import * as storage from '@/lib/localStorage';
|
||||
import { logger } from '@/lib/logger';
|
||||
|
||||
export interface PaginationConfig {
|
||||
/** Initial page number (1-indexed) */
|
||||
initialPage?: number;
|
||||
|
||||
/** Initial page size */
|
||||
initialPageSize?: number;
|
||||
|
||||
/** Whether to persist pagination state */
|
||||
persist?: boolean;
|
||||
|
||||
/** localStorage key for persistence */
|
||||
storageKey?: string;
|
||||
|
||||
/** Callback when page changes */
|
||||
onPageChange?: (page: number) => void;
|
||||
|
||||
/** Callback when page size changes */
|
||||
onPageSizeChange?: (pageSize: number) => void;
|
||||
}
|
||||
|
||||
export interface PaginationState {
|
||||
/** Current page (1-indexed) */
|
||||
currentPage: number;
|
||||
|
||||
/** Items per page */
|
||||
pageSize: number;
|
||||
|
||||
/** Total number of items */
|
||||
totalCount: number;
|
||||
|
||||
/** Total number of pages */
|
||||
totalPages: number;
|
||||
|
||||
/** Start index for current page (0-indexed) */
|
||||
startIndex: number;
|
||||
|
||||
/** End index for current page (0-indexed) */
|
||||
endIndex: number;
|
||||
|
||||
/** Whether there is a previous page */
|
||||
hasPrevPage: boolean;
|
||||
|
||||
/** Whether there is a next page */
|
||||
hasNextPage: boolean;
|
||||
|
||||
/** Set current page */
|
||||
setCurrentPage: (page: number) => void;
|
||||
|
||||
/** Set page size */
|
||||
setPageSize: (size: number) => void;
|
||||
|
||||
/** Set total count */
|
||||
setTotalCount: (count: number) => void;
|
||||
|
||||
/** Go to next page */
|
||||
nextPage: () => void;
|
||||
|
||||
/** Go to previous page */
|
||||
prevPage: () => void;
|
||||
|
||||
/** Go to first page */
|
||||
firstPage: () => void;
|
||||
|
||||
/** Go to last page */
|
||||
lastPage: () => void;
|
||||
|
||||
/** Reset pagination */
|
||||
reset: () => void;
|
||||
|
||||
/** Get page range for display */
|
||||
getPageRange: (maxPages?: number) => number[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for managing pagination state
|
||||
*
|
||||
* @param config - Configuration options
|
||||
* @returns Pagination state and actions
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const pagination = usePagination({
|
||||
* initialPageSize: 25,
|
||||
* persist: true,
|
||||
* onPageChange: (page) => fetchData(page)
|
||||
* });
|
||||
*
|
||||
* // Set total count from API
|
||||
* pagination.setTotalCount(response.count);
|
||||
*
|
||||
* // Use in query
|
||||
* const { startIndex, endIndex } = pagination;
|
||||
* query.range(startIndex, endIndex);
|
||||
* ```
|
||||
*/
|
||||
export function usePagination(config: PaginationConfig = {}): PaginationState {
|
||||
const {
|
||||
initialPage = 1,
|
||||
initialPageSize = MODERATION_CONSTANTS.DEFAULT_PAGE_SIZE,
|
||||
persist = false,
|
||||
storageKey = 'pagination_state',
|
||||
onPageChange,
|
||||
onPageSizeChange,
|
||||
} = config;
|
||||
|
||||
// Load persisted state
|
||||
const loadPersistedState = useCallback(() => {
|
||||
if (!persist) return null;
|
||||
|
||||
try {
|
||||
const saved = localStorage.getItem(storageKey);
|
||||
if (saved) {
|
||||
return JSON.parse(saved);
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
// Silent - localStorage failures are non-critical
|
||||
}
|
||||
|
||||
return null;
|
||||
}, [persist, storageKey]);
|
||||
|
||||
const persisted = loadPersistedState();
|
||||
|
||||
// State
|
||||
const [currentPage, setCurrentPageState] = useState<number>(
|
||||
persisted?.currentPage || initialPage
|
||||
);
|
||||
const [pageSize, setPageSizeState] = useState<number>(
|
||||
persisted?.pageSize || initialPageSize
|
||||
);
|
||||
const [totalCount, setTotalCount] = useState<number>(0);
|
||||
|
||||
// Computed values
|
||||
const totalPages = useMemo(() => Math.ceil(totalCount / pageSize), [totalCount, pageSize]);
|
||||
const startIndex = useMemo(() => (currentPage - 1) * pageSize, [currentPage, pageSize]);
|
||||
const endIndex = useMemo(() => startIndex + pageSize - 1, [startIndex, pageSize]);
|
||||
const hasPrevPage = currentPage > 1;
|
||||
const hasNextPage = currentPage < totalPages;
|
||||
|
||||
// Persist state
|
||||
useEffect(() => {
|
||||
if (persist) {
|
||||
storage.setJSON(storageKey, {
|
||||
currentPage,
|
||||
pageSize,
|
||||
});
|
||||
}
|
||||
}, [currentPage, pageSize, persist, storageKey]);
|
||||
|
||||
// Set current page with bounds checking
|
||||
const setCurrentPage = useCallback(
|
||||
(page: number) => {
|
||||
const boundedPage = Math.max(1, Math.min(page, totalPages || 1));
|
||||
setCurrentPageState(boundedPage);
|
||||
onPageChange?.(boundedPage);
|
||||
},
|
||||
[totalPages, onPageChange]
|
||||
);
|
||||
|
||||
// Set page size and reset to first page
|
||||
const setPageSize = useCallback(
|
||||
(size: number) => {
|
||||
setPageSizeState(size);
|
||||
setCurrentPageState(1);
|
||||
onPageSizeChange?.(size);
|
||||
},
|
||||
[onPageSizeChange]
|
||||
);
|
||||
|
||||
// Navigation actions
|
||||
const nextPage = useCallback(() => {
|
||||
if (hasNextPage) {
|
||||
setCurrentPage(currentPage + 1);
|
||||
}
|
||||
}, [currentPage, hasNextPage, setCurrentPage]);
|
||||
|
||||
const prevPage = useCallback(() => {
|
||||
if (hasPrevPage) {
|
||||
setCurrentPage(currentPage - 1);
|
||||
}
|
||||
}, [currentPage, hasPrevPage, setCurrentPage]);
|
||||
|
||||
const firstPage = useCallback(() => {
|
||||
setCurrentPage(1);
|
||||
}, [setCurrentPage]);
|
||||
|
||||
const lastPage = useCallback(() => {
|
||||
setCurrentPage(totalPages);
|
||||
}, [totalPages, setCurrentPage]);
|
||||
|
||||
// Reset pagination
|
||||
const reset = useCallback(() => {
|
||||
setCurrentPageState(initialPage);
|
||||
setPageSizeState(initialPageSize);
|
||||
setTotalCount(0);
|
||||
}, [initialPage, initialPageSize]);
|
||||
|
||||
// Get page range for pagination controls
|
||||
const getPageRange = useCallback(
|
||||
(maxPages: number = 5): number[] => {
|
||||
if (totalPages <= maxPages) {
|
||||
return Array.from({ length: totalPages }, (_, i) => i + 1);
|
||||
}
|
||||
|
||||
const half = Math.floor(maxPages / 2);
|
||||
let start = Math.max(1, currentPage - half);
|
||||
let end = Math.min(totalPages, start + maxPages - 1);
|
||||
|
||||
// Adjust start if we're near the end
|
||||
if (end - start < maxPages - 1) {
|
||||
start = Math.max(1, end - maxPages + 1);
|
||||
}
|
||||
|
||||
return Array.from({ length: end - start + 1 }, (_, i) => start + i);
|
||||
},
|
||||
[currentPage, totalPages]
|
||||
);
|
||||
|
||||
// Return without useMemo wrapper (OPTIMIZED)
|
||||
return {
|
||||
currentPage,
|
||||
pageSize,
|
||||
totalCount,
|
||||
totalPages,
|
||||
startIndex,
|
||||
endIndex,
|
||||
hasPrevPage,
|
||||
hasNextPage,
|
||||
setCurrentPage,
|
||||
setPageSize,
|
||||
setTotalCount,
|
||||
nextPage,
|
||||
prevPage,
|
||||
firstPage,
|
||||
lastPage,
|
||||
reset,
|
||||
getPageRange,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user