204 lines
5.6 KiB
TypeScript
204 lines
5.6 KiB
TypeScript
// frontend/src/api/hooks/useTenant.ts
|
|
/**
|
|
* Tenant Management Hooks
|
|
*/
|
|
|
|
import { useState, useCallback } from 'react';
|
|
import { tenantService } from '../services';
|
|
import type {
|
|
TenantInfo,
|
|
TenantCreate,
|
|
TenantUpdate,
|
|
TenantMember,
|
|
InviteUser,
|
|
TenantStats,
|
|
} from '../types';
|
|
|
|
export const useTenant = () => {
|
|
const [tenants, setTenants] = useState<TenantInfo[]>([]);
|
|
const [currentTenant, setCurrentTenant] = useState<TenantInfo | null>(null);
|
|
const [members, setMembers] = useState<TenantMember[]>([]);
|
|
const [stats, setStats] = useState<TenantStats | null>(null);
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const createTenant = useCallback(async (data: TenantCreate): Promise<TenantInfo> => {
|
|
try {
|
|
setIsLoading(true);
|
|
setError(null);
|
|
|
|
const tenant = await tenantService.createTenant(data);
|
|
setTenants(prev => [...prev, tenant]);
|
|
setCurrentTenant(tenant);
|
|
|
|
return tenant;
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : 'Failed to create tenant';
|
|
setError(message);
|
|
throw error;
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
const getTenant = useCallback(async (tenantId: string): Promise<TenantInfo> => {
|
|
try {
|
|
setIsLoading(true);
|
|
setError(null);
|
|
|
|
const tenant = await tenantService.getTenant(tenantId);
|
|
setCurrentTenant(tenant);
|
|
|
|
return tenant;
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : 'Failed to get tenant';
|
|
setError(message);
|
|
throw error;
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
const updateTenant = useCallback(async (tenantId: string, data: TenantUpdate): Promise<TenantInfo> => {
|
|
try {
|
|
setIsLoading(true);
|
|
setError(null);
|
|
|
|
const updatedTenant = await tenantService.updateTenant(tenantId, data);
|
|
setCurrentTenant(updatedTenant);
|
|
setTenants(prev => prev.map(t => t.id === tenantId ? updatedTenant : t));
|
|
|
|
return updatedTenant;
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : 'Failed to update tenant';
|
|
setError(message);
|
|
throw error;
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
const getUserTenants = useCallback(async (): Promise<TenantInfo[]> => {
|
|
try {
|
|
setIsLoading(true);
|
|
setError(null);
|
|
|
|
const userTenants = await tenantService.getUserTenants();
|
|
setTenants(userTenants);
|
|
|
|
return userTenants;
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : 'Failed to get user tenants';
|
|
setError(message);
|
|
throw error;
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
const getTenantMembers = useCallback(async (tenantId: string): Promise<TenantMember[]> => {
|
|
try {
|
|
setIsLoading(true);
|
|
setError(null);
|
|
|
|
const response = await tenantService.getTenantMembers(tenantId);
|
|
setMembers(response.data);
|
|
|
|
return response.data;
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : 'Failed to get tenant members';
|
|
setError(message);
|
|
throw error;
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
const inviteUser = useCallback(async (tenantId: string, invitation: InviteUser): Promise<void> => {
|
|
try {
|
|
setIsLoading(true);
|
|
setError(null);
|
|
|
|
await tenantService.inviteUser(tenantId, invitation);
|
|
|
|
// Refresh members list
|
|
await getTenantMembers(tenantId);
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : 'Failed to invite user';
|
|
setError(message);
|
|
throw error;
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, [getTenantMembers]);
|
|
|
|
const removeMember = useCallback(async (tenantId: string, userId: string): Promise<void> => {
|
|
try {
|
|
setIsLoading(true);
|
|
setError(null);
|
|
|
|
await tenantService.removeMember(tenantId, userId);
|
|
setMembers(prev => prev.filter(m => m.user_id !== userId));
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : 'Failed to remove member';
|
|
setError(message);
|
|
throw error;
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
const updateMemberRole = useCallback(async (tenantId: string, userId: string, role: string): Promise<void> => {
|
|
try {
|
|
setIsLoading(true);
|
|
setError(null);
|
|
|
|
const updatedMember = await tenantService.updateMemberRole(tenantId, userId, role);
|
|
setMembers(prev => prev.map(m => m.user_id === userId ? updatedMember : m));
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : 'Failed to update member role';
|
|
setError(message);
|
|
throw error;
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
const getTenantStats = useCallback(async (tenantId: string): Promise<TenantStats> => {
|
|
try {
|
|
setIsLoading(true);
|
|
setError(null);
|
|
|
|
const tenantStats = await tenantService.getTenantStats(tenantId);
|
|
setStats(tenantStats);
|
|
|
|
return tenantStats;
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : 'Failed to get tenant stats';
|
|
setError(message);
|
|
throw error;
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
return {
|
|
tenants,
|
|
currentTenant,
|
|
members,
|
|
stats,
|
|
isLoading,
|
|
error,
|
|
createTenant,
|
|
getTenant,
|
|
updateTenant,
|
|
getUserTenants,
|
|
getTenantMembers,
|
|
inviteUser,
|
|
removeMember,
|
|
updateMemberRole,
|
|
getTenantStats,
|
|
clearError: () => setError(null),
|
|
};
|
|
};
|