← back to Grant

hooks/useClientSort.ts

35 lines

import { useMemo } from 'react';

export interface SortConfig {
  key: string;
  direction: 'asc' | 'desc';
  type: 'string' | 'number' | 'date';
}

export function useClientSort<T>(
  items: T[],
  sortBy: string,
  configs: Record<string, SortConfig>
): T[] {
  return useMemo(() => {
    const config = configs[sortBy];
    if (!config || !items.length) return items;
    return [...items].sort((a, b) => {
      const aVal = (a as Record<string, unknown>)[config.key];
      const bVal = (b as Record<string, unknown>)[config.key];
      if (aVal == null && bVal == null) return 0;
      if (aVal == null) return 1;
      if (bVal == null) return -1;
      let cmp = 0;
      if (config.type === 'date') {
        cmp = new Date(aVal as string).getTime() - new Date(bVal as string).getTime();
      } else if (config.type === 'number') {
        cmp = (Number(aVal) || 0) - (Number(bVal) || 0);
      } else {
        cmp = String(aVal).localeCompare(String(bVal));
      }
      return config.direction === 'desc' ? -cmp : cmp;
    });
  }, [items, sortBy, configs]);
}