// frontend/src/api/services/tenant.service.ts /** * Tenant Management Service * Handles all tenant-related operations */ import { apiClient } from '../client'; import { serviceEndpoints } from '../client/config'; import type { TenantInfo, TenantCreate, TenantUpdate, TenantMember, InviteUser, TenantStats, PaginatedResponse, BaseQueryParams, } from '../types'; export class TenantService { private baseEndpoint = serviceEndpoints.tenant; /** * Create New Tenant */ async createTenant(data: TenantCreate): Promise { return apiClient.post(`${this.baseEndpoint}/register`, data); } /** * Get Tenant Details */ async getTenant(tenantId: string): Promise { return apiClient.get(`${this.baseEndpoint}/${tenantId}`); } /** * Update Tenant */ async updateTenant(tenantId: string, data: TenantUpdate): Promise { return apiClient.put(`${this.baseEndpoint}/${tenantId}`, data); } /** * Delete Tenant */ async deleteTenant(tenantId: string): Promise<{ message: string }> { return apiClient.delete(`${this.baseEndpoint}/${tenantId}`); } /** * Get Tenant Members */ async getTenantMembers( tenantId: string, params?: BaseQueryParams ): Promise> { return apiClient.get(`${this.baseEndpoint}/${tenantId}/members`, { params }); } /** * Invite User to Tenant */ async inviteUser(tenantId: string, invitation: InviteUser): Promise<{ message: string }> { return apiClient.post(`${this.baseEndpoint}/${tenantId}/invite`, invitation); } /** * Remove Member from Tenant */ async removeMember(tenantId: string, userId: string): Promise<{ message: string }> { return apiClient.delete(`${this.baseEndpoint}/${tenantId}/members/${userId}`); } /** * Update Member Role */ async updateMemberRole( tenantId: string, userId: string, role: string ): Promise { return apiClient.patch(`${this.baseEndpoint}/${tenantId}/members/${userId}`, { role }); } /** * Get Tenant Statistics */ async getTenantStats(tenantId: string): Promise { return apiClient.get(`${this.baseEndpoint}/${tenantId}/stats`); } /** * Get User's Tenants - Get tenants where user is owner */ async getUserTenants(): Promise { try { // Extract user ID from the JWT token in localStorage const token = localStorage.getItem('auth_token'); console.log('🔑 TenantService: Auth token present:', !!token); if (!token) { throw new Error('No auth token found'); } // Decode JWT to get user ID (simple base64 decode) const payload = JSON.parse(atob(token.split('.')[1])); const userId = payload.user_id || payload.sub; console.log('👤 TenantService: Extracted user ID:', userId); if (!userId) { throw new Error('No user ID found in token'); } // Get tenants owned by this user const url = `${this.baseEndpoint}/user/${userId}/owned`; console.log('🌐 TenantService: Making request to:', url); const result = await apiClient.get(url); console.log('📦 TenantService: API response:', result); console.log('📏 TenantService: Response length:', Array.isArray(result) ? result.length : 'Not an array'); // Ensure we always return an array if (!Array.isArray(result)) { console.warn('⚠️ TenantService: Response is not an array, converting...'); // If it's an object with numeric keys, convert to array if (result && typeof result === 'object') { const converted = Object.values(result); console.log('🔄 TenantService: Converted to array:', converted); return converted as TenantInfo[]; } console.log('🔄 TenantService: Returning empty array'); return []; } if (result.length > 0) { console.log('✅ TenantService: First tenant:', result[0]); console.log('🆔 TenantService: First tenant ID:', result[0]?.id); } return result; } catch (error) { console.error('❌ TenantService: Failed to get user tenants:', error); // Return empty array if API call fails return []; } } } export const tenantService = new TenantService();