import React, { useState, useEffect } from 'react'; import { useAuth } from '../../contexts/AuthContext'; import { useTenant } from '../../contexts/TenantContext'; import toast from 'react-hot-toast'; import { PlusIcon, MagnifyingGlassIcon } from '@heroicons/react/24/outline'; import UserModal from '../../components/modals/UserModal'; import logger from '../../utils/logger'; interface User { id: string; name: string; email: string; role: 'superuser' | 'tenant_admin' | 'evaluator'; isActive: boolean; } const API_URL = globalThis.__APP_ENV__?.VITE_API_BASE_URL || 'https://duxiter.azurianlab.com/api'; const TenantUsers = () => { const { tenant } = useTenant(); const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [search, setSearch] = useState(''); const [showAddModal, setShowAddModal] = useState(false); const [showEditModal, setShowEditModal] = useState(false); const [selectedUser, setSelectedUser] = useState(null); const [roleFilter, setRoleFilter] = useState(''); const [statusFilter, setStatusFilter] = useState(''); // Fetch users const fetchUsers = async () => { try { const token = localStorage.getItem('token'); const queryParams = new URLSearchParams(); if (search) queryParams.append('search', search); if (roleFilter) queryParams.append('role', roleFilter); if (statusFilter) queryParams.append('status', statusFilter); const response = await fetch(`${API_URL}/users?${queryParams.toString()}`, { headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error('Failed to fetch users'); } const data = await response.json(); if (!data.success) { throw new Error(data.message || 'Failed to fetch users'); } setUsers(data.users || []); } catch (error) { logger.error('Error fetching users:', error); toast.error(error instanceof Error ? error.message : 'Failed to load users'); setUsers([]); // Ensure users is an array to prevent .map error } finally { setLoading(false); } }; useEffect(() => { fetchUsers(); }, [search, roleFilter, statusFilter]); // Toggle user status const toggleUserStatus = async (userId: string) => { try { const token = localStorage.getItem('token'); const response = await fetch(`${API_URL}/users/${userId}/toggle-status`, { method: 'PATCH', headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error('Failed to update user status'); } const data = await response.json(); setUsers(users.map(user => user.id === userId ? { ...user, isActive: data.isActive } : user )); toast.success('User status updated successfully'); } catch (error) { logger.error('Error updating user status:', error); toast.error('Failed to update user status'); } }; return (

Users

Manage users in your organization

{/* Filters */}
setSearch(e.target.value)} placeholder="Search users..." className="block w-full rounded-md border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 pl-10 focus:border-primary-500 focus:ring-primary-500 sm:text-sm text-gray-900 dark:text-white" />
{/* Users Table */}
{users.map((user) => ( ))}
Name Email Role Status Actions
{user.name} {user.email} {user.role === 'tenant_admin' ? 'Admin' : 'Evaluator'} {user.isActive ? 'Active' : 'Inactive'}
{/* Add/Edit User Modal */} { setShowAddModal(false); setShowEditModal(false); setSelectedUser(null); }} user={selectedUser || undefined} onSuccess={fetchUsers} />
); }; export default TenantUsers;