Admin Page work - Still blank/broken
This commit is contained in:
114
frontend/src/features/admin/hooks/useBulkSelection.ts
Normal file
114
frontend/src/features/admin/hooks/useBulkSelection.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* @ai-summary Hook for managing bulk selection state across paginated data
|
||||
* @ai-context Supports individual toggle, select all, and reset operations
|
||||
*/
|
||||
|
||||
import { useState, useCallback, useMemo } from 'react';
|
||||
|
||||
/**
|
||||
* Options for bulk selection hook
|
||||
*/
|
||||
interface UseBulkSelectionOptions<T> {
|
||||
items: T[];
|
||||
keyExtractor?: (item: T) => string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return type for bulk selection hook
|
||||
*/
|
||||
interface UseBulkSelectionReturn<T> {
|
||||
selected: Set<string>;
|
||||
toggleItem: (id: string) => void;
|
||||
toggleAll: (items: T[]) => void;
|
||||
isSelected: (id: string) => boolean;
|
||||
reset: () => void;
|
||||
count: number;
|
||||
selectedItems: T[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom hook for managing bulk selection state
|
||||
* Supports selection across pagination boundaries
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const { selected, toggleItem, toggleAll, reset, count } = useBulkSelection({ items: data });
|
||||
* ```
|
||||
*/
|
||||
export function useBulkSelection<T extends { id: string }>(
|
||||
options: UseBulkSelectionOptions<T>
|
||||
): UseBulkSelectionReturn<T> {
|
||||
const { items, keyExtractor = (item: T) => item.id } = options;
|
||||
|
||||
const [selected, setSelected] = useState<Set<string>>(new Set());
|
||||
|
||||
/**
|
||||
* Toggle individual item selection
|
||||
*/
|
||||
const toggleItem = useCallback((id: string) => {
|
||||
setSelected((prev) => {
|
||||
const next = new Set(prev);
|
||||
if (next.has(id)) {
|
||||
next.delete(id);
|
||||
} else {
|
||||
next.add(id);
|
||||
}
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Toggle all items - if all are selected, deselect all; otherwise select all
|
||||
* This supports "Select All" across pagination
|
||||
*/
|
||||
const toggleAll = useCallback((itemsToToggle: T[]) => {
|
||||
setSelected((prev) => {
|
||||
const itemIds = itemsToToggle.map(keyExtractor);
|
||||
const allSelected = itemIds.every((id) => prev.has(id));
|
||||
|
||||
if (allSelected) {
|
||||
// Deselect all items
|
||||
const next = new Set(prev);
|
||||
itemIds.forEach((id) => next.delete(id));
|
||||
return next;
|
||||
} else {
|
||||
// Select all items
|
||||
const next = new Set(prev);
|
||||
itemIds.forEach((id) => next.add(id));
|
||||
return next;
|
||||
}
|
||||
});
|
||||
}, [keyExtractor]);
|
||||
|
||||
/**
|
||||
* Check if item is selected
|
||||
*/
|
||||
const isSelected = useCallback(
|
||||
(id: string) => selected.has(id),
|
||||
[selected]
|
||||
);
|
||||
|
||||
/**
|
||||
* Clear all selections
|
||||
*/
|
||||
const reset = useCallback(() => {
|
||||
setSelected(new Set());
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Get array of selected items from current items list
|
||||
*/
|
||||
const selectedItems = useMemo(() => {
|
||||
return items.filter((item) => selected.has(keyExtractor(item)));
|
||||
}, [items, selected, keyExtractor]);
|
||||
|
||||
return {
|
||||
selected,
|
||||
toggleItem,
|
||||
toggleAll,
|
||||
isSelected,
|
||||
reset,
|
||||
count: selected.size,
|
||||
selectedItems,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user