Fix jwt-token
This commit is contained in:
@@ -10,7 +10,9 @@ import {
|
||||
GlobeAltIcon,
|
||||
KeyIcon,
|
||||
EyeIcon,
|
||||
EyeSlashIcon
|
||||
EyeSlashIcon,
|
||||
TrashIcon,
|
||||
PencilIcon
|
||||
} from '@heroicons/react/24/outline';
|
||||
import { hasPermission, canAccessSettings } from '../utils/rbac';
|
||||
|
||||
@@ -1099,6 +1101,8 @@ const UsersSettings = ({ tenantConfig, onRefresh }) => {
|
||||
const [showCreateUser, setShowCreateUser] = useState(false);
|
||||
const [showEditUser, setShowEditUser] = useState(false);
|
||||
const [editingUser, setEditingUser] = useState(null);
|
||||
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
||||
const [deletingUser, setDeletingUser] = useState(null);
|
||||
|
||||
const authProvider = tenantConfig?.auth_provider;
|
||||
const isLocalAuth = authProvider === 'local';
|
||||
@@ -1260,25 +1264,41 @@ const UsersSettings = ({ tenantConfig, onRefresh }) => {
|
||||
</td>
|
||||
{(canEditUsers || canDeleteUsers) && (
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium">
|
||||
{canEditUsers && (
|
||||
<button
|
||||
onClick={() => handleEditUser(user)}
|
||||
className="text-primary-600 hover:text-primary-900 mr-4"
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
)}
|
||||
{canDeleteUsers && (
|
||||
<button
|
||||
onClick={() => handleToggleUserStatus(user)}
|
||||
className={user.is_active
|
||||
? 'text-red-600 hover:text-red-900'
|
||||
: 'text-green-600 hover:text-green-900'
|
||||
}
|
||||
>
|
||||
{user.is_active ? 'Deactivate' : 'Activate'}
|
||||
</button>
|
||||
)}
|
||||
<div className="flex items-center space-x-2">
|
||||
{canEditUsers && (
|
||||
<button
|
||||
onClick={() => handleEditUser(user)}
|
||||
className="inline-flex items-center px-2 py-1 border border-transparent text-xs font-medium rounded text-blue-700 bg-blue-100 hover:bg-blue-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
||||
title="Edit user"
|
||||
>
|
||||
<PencilIcon className="h-3 w-3 mr-1" />
|
||||
Edit
|
||||
</button>
|
||||
)}
|
||||
{canDeleteUsers && (
|
||||
<button
|
||||
onClick={() => handleToggleUserStatus(user)}
|
||||
className={`inline-flex items-center px-2 py-1 border border-transparent text-xs font-medium rounded focus:outline-none focus:ring-2 focus:ring-offset-2 ${
|
||||
user.is_active
|
||||
? 'text-orange-700 bg-orange-100 hover:bg-orange-200 focus:ring-orange-500'
|
||||
: 'text-green-700 bg-green-100 hover:bg-green-200 focus:ring-green-500'
|
||||
}`}
|
||||
title={user.is_active ? 'Deactivate user' : 'Activate user'}
|
||||
>
|
||||
{user.is_active ? 'Deactivate' : 'Activate'}
|
||||
</button>
|
||||
)}
|
||||
{canDeleteUsers && (
|
||||
<button
|
||||
onClick={() => handleDeleteUser(user)}
|
||||
className="inline-flex items-center px-2 py-1 border border-transparent text-xs font-medium rounded text-red-700 bg-red-100 hover:bg-red-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"
|
||||
title="Delete user permanently"
|
||||
>
|
||||
<TrashIcon className="h-3 w-3 mr-1" />
|
||||
Delete
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
)}
|
||||
</tr>
|
||||
@@ -1349,6 +1369,43 @@ const UsersSettings = ({ tenantConfig, onRefresh }) => {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Delete Confirmation Modal */}
|
||||
{showDeleteConfirm && deletingUser && (
|
||||
<div className="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50">
|
||||
<div className="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white">
|
||||
<div className="mt-3 text-center">
|
||||
<div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-red-100">
|
||||
<TrashIcon className="h-6 w-6 text-red-600" />
|
||||
</div>
|
||||
<h3 className="text-lg font-medium text-gray-900 mt-4">Delete User</h3>
|
||||
<div className="mt-2 px-7 py-3">
|
||||
<p className="text-sm text-gray-500">
|
||||
Are you sure you want to delete <strong>{deletingUser.username}</strong>?
|
||||
This action cannot be undone and will permanently remove the user and all associated data.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex justify-center space-x-4 mt-4">
|
||||
<button
|
||||
onClick={() => {
|
||||
setShowDeleteConfirm(false);
|
||||
setDeletingUser(null);
|
||||
}}
|
||||
className="px-4 py-2 bg-gray-300 text-gray-700 rounded-md hover:bg-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-500"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
onClick={confirmDeleteUser}
|
||||
className="px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500"
|
||||
>
|
||||
Delete User
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1369,6 +1426,25 @@ const UsersSettings = ({ tenantConfig, onRefresh }) => {
|
||||
toast.error('Failed to update user status');
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteUser = (user) => {
|
||||
setDeletingUser(user);
|
||||
setShowDeleteConfirm(true);
|
||||
};
|
||||
|
||||
const confirmDeleteUser = async () => {
|
||||
if (!deletingUser) return;
|
||||
|
||||
try {
|
||||
await api.delete(`/tenant/users/${deletingUser.id}`);
|
||||
toast.success('User deleted successfully');
|
||||
fetchUsers();
|
||||
setShowDeleteConfirm(false);
|
||||
setDeletingUser(null);
|
||||
} catch (error) {
|
||||
toast.error('Failed to delete user');
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Create User Modal Component (for local auth only)
|
||||
|
||||
Reference in New Issue
Block a user