172 lines
3.4 KiB
JavaScript
172 lines
3.4 KiB
JavaScript
import { useState, useMemo } from 'react';
|
|
import { useUsers } from '../context/UsersContext';
|
|
|
|
const DEFAULT_SEARCH_FIELDS = ['first_name', 'last_name', 'email'];
|
|
|
|
/**
|
|
* Base hook that adds search and filter functionality to any user list
|
|
*/
|
|
const useFilteredUsers = ({
|
|
users,
|
|
initialFilter = 'all',
|
|
filterKey = 'status',
|
|
searchFields = DEFAULT_SEARCH_FIELDS,
|
|
searchAccessor,
|
|
}) => {
|
|
const [searchQuery, setSearchQuery] = useState('');
|
|
const [filterValue, setFilterValue] = useState(initialFilter);
|
|
|
|
const filteredUsers = useMemo(() => {
|
|
let filtered = users;
|
|
|
|
// Apply filter
|
|
if (filterValue && filterValue !== 'all') {
|
|
filtered = filtered.filter(user => user[filterKey] === filterValue);
|
|
}
|
|
|
|
// Apply search
|
|
if (searchQuery) {
|
|
const query = searchQuery.toLowerCase();
|
|
filtered = filtered.filter(user => {
|
|
const values = typeof searchAccessor === 'function'
|
|
? searchAccessor(user)
|
|
: searchFields.map(field => user?.[field]);
|
|
|
|
return values
|
|
.filter(Boolean)
|
|
.some(value => value.toString().toLowerCase().includes(query));
|
|
});
|
|
}
|
|
|
|
return filtered;
|
|
}, [users, searchQuery, filterKey, filterValue, searchAccessor, searchFields]);
|
|
|
|
return {
|
|
filteredUsers,
|
|
searchQuery,
|
|
setSearchQuery,
|
|
filterValue,
|
|
setFilterValue,
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Hook for staff users (admin, superadmin, finance roles)
|
|
*/
|
|
export const useStaff = ({
|
|
initialFilter = 'all',
|
|
filterKey = 'role',
|
|
searchFields = DEFAULT_SEARCH_FIELDS,
|
|
searchAccessor,
|
|
} = {}) => {
|
|
const { staff, loading, error, refetch, updateUser, removeUser } = useUsers();
|
|
|
|
const {
|
|
filteredUsers,
|
|
searchQuery,
|
|
setSearchQuery,
|
|
filterValue,
|
|
setFilterValue,
|
|
} = useFilteredUsers({
|
|
users: staff,
|
|
initialFilter,
|
|
filterKey,
|
|
searchFields,
|
|
searchAccessor,
|
|
});
|
|
|
|
return {
|
|
users: staff,
|
|
filteredUsers,
|
|
loading,
|
|
error,
|
|
searchQuery,
|
|
setSearchQuery,
|
|
filterValue,
|
|
setFilterValue,
|
|
refetch,
|
|
updateUser,
|
|
removeUser,
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Hook for member users (non-admin roles)
|
|
*/
|
|
export const useMembers = ({
|
|
initialFilter = 'active',
|
|
filterKey = 'status',
|
|
searchFields = DEFAULT_SEARCH_FIELDS,
|
|
searchAccessor,
|
|
} = {}) => {
|
|
const { members, loading, error, refetch, updateUser, removeUser } = useUsers();
|
|
|
|
const {
|
|
filteredUsers,
|
|
searchQuery,
|
|
setSearchQuery,
|
|
filterValue,
|
|
setFilterValue,
|
|
} = useFilteredUsers({
|
|
users: members,
|
|
initialFilter,
|
|
filterKey,
|
|
searchFields,
|
|
searchAccessor,
|
|
});
|
|
|
|
return {
|
|
users: members,
|
|
filteredUsers,
|
|
loading,
|
|
error,
|
|
searchQuery,
|
|
setSearchQuery,
|
|
filterValue,
|
|
setFilterValue,
|
|
refetch,
|
|
updateUser,
|
|
removeUser,
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Hook for all users (both staff and members)
|
|
*/
|
|
export const useAllUsers = ({
|
|
initialFilter = 'all',
|
|
filterKey = 'status',
|
|
searchFields = DEFAULT_SEARCH_FIELDS,
|
|
searchAccessor,
|
|
} = {}) => {
|
|
const { users, loading, error, refetch, updateUser, removeUser } = useUsers();
|
|
|
|
const {
|
|
filteredUsers,
|
|
searchQuery,
|
|
setSearchQuery,
|
|
filterValue,
|
|
setFilterValue,
|
|
} = useFilteredUsers({
|
|
users,
|
|
initialFilter,
|
|
filterKey,
|
|
searchFields,
|
|
searchAccessor,
|
|
});
|
|
|
|
return {
|
|
users,
|
|
filteredUsers,
|
|
loading,
|
|
error,
|
|
searchQuery,
|
|
setSearchQuery,
|
|
filterValue,
|
|
setFilterValue,
|
|
refetch,
|
|
updateUser,
|
|
removeUser,
|
|
};
|
|
};
|