163 lines
4.2 KiB
TypeScript
163 lines
4.2 KiB
TypeScript
|
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||
|
|
import { apiPost, apiGet, apiPatch, apiDelete } from './client';
|
||
|
|
import { useAuthStore } from '@/store/authStore';
|
||
|
|
|
||
|
|
export interface LoginPayload {
|
||
|
|
email: string;
|
||
|
|
password: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface PasswordResetRequestPayload {
|
||
|
|
email: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface PasswordResetConfirmPayload {
|
||
|
|
token: string;
|
||
|
|
password: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface PaginatedResponse<T> {
|
||
|
|
items: T[];
|
||
|
|
total: number;
|
||
|
|
page: number;
|
||
|
|
page_size: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useLogin() {
|
||
|
|
const { setUser, setError } = useAuthStore();
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: (payload: LoginPayload) =>
|
||
|
|
apiPost('/auth/login', payload),
|
||
|
|
onSuccess: (data: any) => {
|
||
|
|
setUser(data.user || data);
|
||
|
|
setError(null);
|
||
|
|
},
|
||
|
|
onError: (error: any) => {
|
||
|
|
setError(error.message || 'Login failed');
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useLogout() {
|
||
|
|
const { logout } = useAuthStore();
|
||
|
|
const queryClient = useQueryClient();
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: () => apiPost('/auth/logout'),
|
||
|
|
onSettled: () => {
|
||
|
|
logout();
|
||
|
|
queryClient.clear();
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useCurrentUser() {
|
||
|
|
const { setUser, setAuthenticated } = useAuthStore();
|
||
|
|
return useQuery({
|
||
|
|
queryKey: ['currentUser'],
|
||
|
|
queryFn: async () => {
|
||
|
|
const data = await apiGet<any>('/auth/me');
|
||
|
|
setUser(data.user || data);
|
||
|
|
setAuthenticated(true);
|
||
|
|
return data;
|
||
|
|
},
|
||
|
|
retry: false,
|
||
|
|
staleTime: 5 * 60 * 1000,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function usePasswordResetRequest() {
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: (payload: PasswordResetRequestPayload) =>
|
||
|
|
apiPost('/auth/password-reset/request', payload),
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function usePasswordResetConfirm() {
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: (payload: PasswordResetConfirmPayload) =>
|
||
|
|
apiPost('/auth/password-reset/confirm', payload),
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useSwitchTenant() {
|
||
|
|
const { setTenant } = useAuthStore();
|
||
|
|
const queryClient = useQueryClient();
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: (tenantId: string) =>
|
||
|
|
apiPost('/auth/switch-tenant', { tenant_id: tenantId }),
|
||
|
|
onSuccess: (data: any) => {
|
||
|
|
setTenant(data.tenant || data);
|
||
|
|
queryClient.invalidateQueries();
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useUsers(page = 1, pageSize = 25) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: ['users', page, pageSize],
|
||
|
|
queryFn: () =>
|
||
|
|
apiGet<PaginatedResponse<any>>(`/users?page=${page}&page_size=${pageSize}`),
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useCompanies(page = 1, pageSize = 25, search?: string) {
|
||
|
|
const params = new URLSearchParams({ page: String(page), page_size: String(pageSize) });
|
||
|
|
if (search) params.set('search', search);
|
||
|
|
return useQuery({
|
||
|
|
queryKey: ['companies', page, pageSize, search],
|
||
|
|
queryFn: () =>
|
||
|
|
apiGet<PaginatedResponse<any>>(`/companies?${params.toString()}`),
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useContacts(page = 1, pageSize = 25, search?: string) {
|
||
|
|
const params = new URLSearchParams({ page: String(page), page_size: String(pageSize) });
|
||
|
|
if (search) params.set('search', search);
|
||
|
|
return useQuery({
|
||
|
|
queryKey: ['contacts', page, pageSize, search],
|
||
|
|
queryFn: () =>
|
||
|
|
apiGet<PaginatedResponse<any>>(`/contacts?${params.toString()}`),
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useNotifications() {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: ['notifications'],
|
||
|
|
queryFn: () => apiGet<PaginatedResponse<any>>('/notifications'),
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useUnreadNotificationCount() {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: ['notifications', 'unread-count'],
|
||
|
|
queryFn: () => apiGet<number>('/notifications/unread-count'),
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useMarkNotificationRead() {
|
||
|
|
const queryClient = useQueryClient();
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: (id: string) => apiPatch(`/notifications/${id}/read`),
|
||
|
|
onSuccess: () => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: ['notifications'] });
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useDeleteNotification() {
|
||
|
|
const queryClient = useQueryClient();
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: (id: string) => apiDelete(`/notifications/${id}`),
|
||
|
|
onSuccess: () => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: ['notifications'] });
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function usePlugins() {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: ['plugins'],
|
||
|
|
queryFn: () => apiGet<any[]>('/plugins'),
|
||
|
|
});
|
||
|
|
}
|