feat: add multi-tenant client management for admins
- Add tenants API endpoints (list, get, create) - Add tenant middleware override via X-View-Tenant header - Add TenantSelector dropdown component in header - Add tenant view store with persistence - Add Clientes management page - Update all navigation layouts with Clientes link for admins Admins can now: - View list of all clients - Create new clients with automatic schema setup - Switch between viewing different clients' data - See which client they are currently viewing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,19 @@ apiClient.interceptors.request.use((config) => {
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
// Add viewing tenant header for admin users
|
||||
const tenantViewStore = localStorage.getItem('horux-tenant-view');
|
||||
if (tenantViewStore) {
|
||||
try {
|
||||
const { state } = JSON.parse(tenantViewStore);
|
||||
if (state?.viewingTenantId) {
|
||||
config.headers['X-View-Tenant'] = state.viewingTenantId;
|
||||
}
|
||||
} catch {
|
||||
// Ignore parse errors
|
||||
}
|
||||
}
|
||||
}
|
||||
return config;
|
||||
});
|
||||
|
||||
36
apps/web/lib/api/tenants.ts
Normal file
36
apps/web/lib/api/tenants.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { apiClient } from './client';
|
||||
|
||||
export interface Tenant {
|
||||
id: string;
|
||||
nombre: string;
|
||||
rfc: string;
|
||||
plan: string;
|
||||
schemaName: string;
|
||||
createdAt: string;
|
||||
_count?: {
|
||||
users: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface CreateTenantData {
|
||||
nombre: string;
|
||||
rfc: string;
|
||||
plan?: 'starter' | 'business' | 'professional' | 'enterprise';
|
||||
cfdiLimit?: number;
|
||||
usersLimit?: number;
|
||||
}
|
||||
|
||||
export async function getTenants(): Promise<Tenant[]> {
|
||||
const response = await apiClient.get<Tenant[]>('/tenants');
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export async function getTenant(id: string): Promise<Tenant> {
|
||||
const response = await apiClient.get<Tenant>(`/tenants/${id}`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export async function createTenant(data: CreateTenantData): Promise<Tenant> {
|
||||
const response = await apiClient.post<Tenant>('/tenants', data);
|
||||
return response.data;
|
||||
}
|
||||
Reference in New Issue
Block a user