- Users page: paginated, searchable, sortable with inline roles (no N+1) - Roles page: paginated, searchable, sortable + /roles/all for dropdowns - User is_active field with migration, PATCH toggle, auth check (disabled=401) - Frontend permission checks: auth store loads permissions, sidebar/buttons conditional - Profile pictures via file storage for users and members, avatar component - Identifier images use file storage API instead of base64 - Fix TypeScript errors across admin UI - 64 API tests passing (10 new)
46 lines
1.2 KiB
TypeScript
46 lines
1.2 KiB
TypeScript
import { queryOptions } from '@tanstack/react-query'
|
|
import { api } from '@/lib/api-client'
|
|
import type { PaginationInput, PaginatedResponse } from '@forte/shared/schemas'
|
|
|
|
export interface UserRole {
|
|
id: string
|
|
name: string
|
|
slug: string
|
|
isSystem: boolean
|
|
}
|
|
|
|
export interface UserRecord {
|
|
id: string
|
|
email: string
|
|
firstName: string
|
|
lastName: string
|
|
role: string
|
|
isActive: boolean
|
|
createdAt: string
|
|
roles: UserRole[]
|
|
}
|
|
|
|
export const userKeys = {
|
|
list: (params: PaginationInput) => ['users', params] as const,
|
|
roles: (userId: string) => ['users', userId, 'roles'] as const,
|
|
}
|
|
|
|
export function userListOptions(params: PaginationInput) {
|
|
return queryOptions({
|
|
queryKey: userKeys.list(params),
|
|
queryFn: () => api.get<PaginatedResponse<UserRecord>>('/v1/users', params as Record<string, unknown>),
|
|
})
|
|
}
|
|
|
|
export function userRolesOptions(userId: string) {
|
|
return queryOptions({
|
|
queryKey: userKeys.roles(userId),
|
|
queryFn: () => api.get<{ data: UserRole[] }>(`/v1/users/${userId}/roles`),
|
|
})
|
|
}
|
|
|
|
export const userMutations = {
|
|
toggleStatus: (userId: string, isActive: boolean) =>
|
|
api.patch<{ id: string; isActive: boolean }>(`/v1/users/${userId}/status`, { isActive }),
|
|
}
|