'use client' import { useState, useEffect, useCallback } from 'react' import type { TabId, Tenant, Namespace, Role, UserRole, LLMPolicy } from './types' import { SDK_BASE_URL } from './types' export interface RbacStats { tenants: number namespaces: number roles: number systemRoles: number policies: number activeUsers: number } export function useRbacData() { const [activeTab, setActiveTab] = useState('tenants') const [loading, setLoading] = useState(true) const [error, setError] = useState(null) // Data states const [tenants, setTenants] = useState([]) const [namespaces, setNamespaces] = useState([]) const [roles, setRoles] = useState([]) const [userRoles, setUserRoles] = useState([]) const [policies, setPolicies] = useState([]) // Filter states const [selectedTenantId, setSelectedTenantId] = useState('') const [searchTerm, setSearchTerm] = useState('') // Modal states const [showCreateModal, setShowCreateModal] = useState(false) const [editItem, setEditItem] = useState(null) // Load data based on active tab const loadData = useCallback(async () => { setLoading(true) setError(null) try { const headers: Record = { 'Content-Type': 'application/json', } if (selectedTenantId) { headers['X-Tenant-ID'] = selectedTenantId } switch (activeTab) { case 'tenants': { const res = await fetch(`${SDK_BASE_URL}/sdk/v1/tenants`, { headers }) if (res.ok) { const data = await res.json() setTenants(data.tenants || []) } break } case 'namespaces': { if (!selectedTenantId) { setNamespaces([]) break } const res = await fetch(`${SDK_BASE_URL}/sdk/v1/tenants/${selectedTenantId}/namespaces`, { headers }) if (res.ok) { const data = await res.json() setNamespaces(data.namespaces || []) } break } case 'roles': { const res = await fetch(`${SDK_BASE_URL}/sdk/v1/roles`, { headers }) if (res.ok) { const data = await res.json() setRoles(data.roles || []) } break } case 'users': { // This would need a user ID - for now show empty setUserRoles([]) break } case 'policies': { const res = await fetch(`${SDK_BASE_URL}/sdk/v1/llm/policies`, { headers }) if (res.ok) { const data = await res.json() setPolicies(data.policies || []) } break } } } catch (err) { console.error('Failed to load data:', err) setError('Verbindung zum AI Compliance SDK fehlgeschlagen. Stellen Sie sicher, dass der SDK-Service laeuft.') } finally { setLoading(false) } }, [activeTab, selectedTenantId]) useEffect(() => { loadData() }, [loadData]) // Load tenants on mount for the filter useEffect(() => { const loadTenants = async () => { try { const res = await fetch(`${SDK_BASE_URL}/sdk/v1/tenants`) if (res.ok) { const data = await res.json() setTenants(data.tenants || []) if (data.tenants?.length > 0 && !selectedTenantId) { setSelectedTenantId(data.tenants[0].id) } } } catch (err) { console.error('Failed to load tenants:', err) } } loadTenants() }, []) const handleCreate = async (data: any) => { try { const headers: Record = { 'Content-Type': 'application/json', } if (selectedTenantId) { headers['X-Tenant-ID'] = selectedTenantId } let endpoint = '' switch (activeTab) { case 'tenants': endpoint = `${SDK_BASE_URL}/sdk/v1/tenants` break case 'namespaces': endpoint = `${SDK_BASE_URL}/sdk/v1/tenants/${selectedTenantId}/namespaces` break case 'roles': endpoint = `${SDK_BASE_URL}/sdk/v1/roles` break case 'policies': endpoint = `${SDK_BASE_URL}/sdk/v1/llm/policies` break } const res = await fetch(endpoint, { method: 'POST', headers, body: JSON.stringify(data), }) if (res.ok) { setShowCreateModal(false) loadData() } else { const errData = await res.json() alert(`Fehler: ${errData.error || 'Unbekannter Fehler'}`) } } catch (err) { console.error('Create failed:', err) alert('Erstellen fehlgeschlagen') } } const filteredData = () => { const term = searchTerm.toLowerCase() switch (activeTab) { case 'tenants': return tenants.filter(t => t.name.toLowerCase().includes(term) || t.slug.toLowerCase().includes(term) ) case 'namespaces': return namespaces.filter(n => n.name.toLowerCase().includes(term) || n.slug.toLowerCase().includes(term) ) case 'roles': return roles.filter(r => r.name.toLowerCase().includes(term) || r.description?.toLowerCase().includes(term) ) case 'policies': return policies.filter(p => p.name.toLowerCase().includes(term) ) default: return [] } } const stats: RbacStats = { tenants: tenants.length, namespaces: namespaces.length, roles: roles.length, systemRoles: roles.filter(r => r.is_system_role).length, policies: policies.length, activeUsers: userRoles.length, } return { activeTab, setActiveTab, loading, error, tenants, userRoles, selectedTenantId, setSelectedTenantId, searchTerm, setSearchTerm, showCreateModal, setShowCreateModal, editItem, setEditItem, handleCreate, filteredData, stats, } }