Files
leocrm/frontend/src/api/hooks.ts
T

137 lines
4.3 KiB
TypeScript
Raw Normal View History

/**
* hooks.ts — Re-Export Hub
*
* This file re-exports all hooks from their dedicated modules so that
* existing imports `from '@/api/hooks'` continue to work without change.
*
* Company hooks remain inline here — they will be removed in Phase 1.
*/
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { apiGet, apiPost, apiPatch, apiDelete, apiClient } from './client';
import { PaginatedResponse, Company, CompanyDetail } from './types';
// ── Re-exports from dedicated modules ──
export * from './types';
export * from './auth';
export * from './users';
export * from './contacts';
export * from './roles';
export * from './groups';
export * from './audit';
export * from './notifications';
export * from './plugins';
export * from './settings';
export * from './attachments';
export * from './unifiedContacts';
// ── Search hook (uses dynamic import, kept inline) ──
export interface SearchResult {
type: 'company' | 'contact' | 'mail' | 'file' | 'event';
id: string;
name: string;
description?: string;
url: string;
}
export function useGlobalSearch(query: string, entityTypes?: string[]) {
return useQuery({
queryKey: ['globalSearch', query, entityTypes],
queryFn: async (): Promise<SearchResult[]> => {
if (!query.trim()) return [];
const { search } = await import('@/api/search');
const response = await search(query, entityTypes, 20);
return response.results || [];
},
enabled: query.trim().length > 0,
staleTime: 30 * 1000,
});
}
// ── Company hooks (will be removed in Phase 1) ──
export function useCompanies(page = 1, pageSize = 25, search?: string, industry?: string, sortBy?: string, sortOrder?: string) {
const params = new URLSearchParams({ page: String(page), page_size: String(pageSize) });
if (search) params.set('search', search);
if (industry) params.set('industry', industry);
if (sortBy) params.set('sort_by', sortBy);
if (sortOrder) params.set('sort_order', sortOrder);
return useQuery({
queryKey: ['companies', page, pageSize, search, industry, sortBy, sortOrder],
queryFn: () =>
apiGet<PaginatedResponse<Company>>(`/companies?${params.toString()}`),
});
}
export function useCompany(id?: string) {
return useQuery({
queryKey: ['companies', id],
queryFn: () => apiGet<CompanyDetail>(`/companies/${id}`),
enabled: !!id,
});
}
export function useCreateCompany() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: Partial<Company>) => apiPost('/companies', data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['companies'] });
},
});
}
export function useUpdateCompany() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, data }: { id: string; data: Partial<Company> }) =>
apiPatch(`/companies/${id}`, data),
onSuccess: (_data, variables) => {
queryClient.invalidateQueries({ queryKey: ['companies'] });
queryClient.invalidateQueries({ queryKey: ['companies', variables.id] });
},
});
}
export function useDeleteCompany() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (id: string) => apiDelete(`/companies/${id}`),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['companies'] });
},
});
}
export function useCompanyExport(search?: string, industry?: string) {
return useMutation({
mutationFn: async () => {
const params = new URLSearchParams({ format: 'csv' });
if (search) params.set('search', search);
if (industry) params.set('industry', industry);
const response = await apiClient.get(`/companies/export?${params.toString()}`, {
responseType: 'blob',
});
return response.data;
},
});
}
export function useCompanyImport() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (file: File) => {
const formData = new FormData();
formData.append('file', file);
const response = await apiClient.post('/companies/import', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
});
return response.data;
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['companies'] });
},
});
}