> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Braian551/viax/llms.txt
> Use this file to discover all available pages before exploring further.

# User Management

> Manage platform users, edit profiles, and control account status

## Overview

The User Management screen provides comprehensive tools for managing all platform users including clients, drivers, and company accounts.

## Accessing User Management

<Steps>
  <Step title="Navigate to Management Tab">
    From the admin panel, select the "Gestión" tab
  </Step>

  <Step title="Select User Management">
    Tap on "Gestión de Usuarios" card
  </Step>

  <Step title="View User List">
    All users display with filtering and search options
  </Step>
</Steps>

## User Management Provider

User management uses a dedicated provider for state management:

```dart admin/presentation/providers/user_management_provider.dart theme={null}
class AdminUserManagementProvider with ChangeNotifier {
  final GetUsersUseCase getUsersUseCase;
  final ManageUserUseCase manageUserUseCase;
  final int adminId;

  List<dynamic> _users = [];
  String? _currentFilter; // 'cliente', 'conductor', 'empresa', or null
  String? _searchQuery;
  bool _showInactive = false; // false = active, true = inactive

  Future<void> loadUsers({bool refresh = false}) async {
    final result = await getUsersUseCase(
      adminId: adminId,
      page: _currentPage,
      search: _searchQuery,
      tipoUsuario: _currentFilter,
      esActivo: !_showInactive,
    );
  }
}
```

## Search and Filters

### Search Bar

Search users by name, email, or phone number:

```dart admin/presentation/screens/users_management_screen.dart theme={null}
Widget _buildSearchBar() {
  return Container(
    decoration: BoxDecoration(
      color: AppColors.darkSurface.withValues(alpha: 0.8),
      borderRadius: BorderRadius.circular(14),
      border: Border.all(color: Colors.white12),
    ),
    child: TextField(
      controller: _searchController,
      decoration: InputDecoration(
        hintText: 'Buscar por nombre, email o teléfono...',
        prefixIcon: Icon(Icons.search_rounded),
        suffixIcon: _searchController.text.isNotEmpty
            ? IconButton(
                icon: Icon(Icons.clear_rounded),
                onPressed: () {
                  _searchController.clear();
                  _provider.setSearchQuery('');
                },
              )
            : null,
      ),
      onSubmitted: (value) => _provider.setSearchQuery(value),
    ),
  );
}
```

### User Type Filters

<Tabs>
  <Tab title="All Users">
    Display all users regardless of type

    **Filter Value:** `null`
  </Tab>

  <Tab title="Clients">
    Show only passenger accounts

    **Filter Value:** `'cliente'`

    **Color:** Green (#11998e)
  </Tab>

  <Tab title="Drivers">
    Show only driver accounts

    **Filter Value:** `'conductor'`

    **Color:** Blue (#667eea)
  </Tab>

  <Tab title="Companies">
    Show only company accounts

    **Filter Value:** `'empresa'`

    **Color:** Orange (#ffa726)
  </Tab>
</Tabs>

### Active/Inactive Toggle

Switch between viewing active or inactive users:

```dart admin/presentation/screens/users_management_screen.dart theme={null}
GestureDetector(
  onTap: () {
    _provider.setShowInactive(!_provider.showInactive);
    setState(() {});
  },
  child: AnimatedContainer(
    duration: const Duration(milliseconds: 200),
    decoration: BoxDecoration(
      color: _provider.showInactive 
          ? Colors.red.withValues(alpha: 0.15)
          : AppColors.success.withValues(alpha: 0.15),
      borderRadius: BorderRadius.circular(20),
      border: Border.all(
        color: _provider.showInactive ? Colors.red : AppColors.success,
      ),
    ),
    child: Row(
      children: [
        Icon(
          _provider.showInactive 
              ? Icons.person_off_rounded 
              : Icons.person_rounded,
        ),
        Text(_provider.showInactive ? 'Inactivos' : 'Activos'),
      ],
    ),
  ),
)
```

## Filter Chip Implementation

```dart admin/presentation/screens/users_management_screen.dart theme={null}
Widget _buildFilterChip({
  required String label,
  required bool isSelected,
  Color? color,
  required VoidCallback onTap,
}) {
  final chipColor = color ?? AppColors.primary;
  
  return GestureDetector(
    onTap: onTap,
    child: AnimatedContainer(
      duration: const Duration(milliseconds: 200),
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
      decoration: BoxDecoration(
        color: isSelected
            ? chipColor.withValues(alpha: 0.15)
            : Colors.transparent,
        borderRadius: BorderRadius.circular(20),
        border: Border.all(
          color: isSelected ? chipColor : Colors.grey.withValues(alpha: 0.3),
        ),
      ),
      child: Text(label),
    ),
  );
}
```

## User List Display

Users are displayed in an interactive, scrollable list:

```dart admin/presentation/screens/users_management_screen.dart theme={null}
Widget _buildUsersList(AdminUserManagementProvider provider) {
  return RefreshIndicator(
    onRefresh: () async => provider.loadUsers(refresh: true),
    child: ListView.builder(
      padding: const EdgeInsets.symmetric(horizontal: 16),
      physics: const BouncingScrollPhysics(
        parent: AlwaysScrollableScrollPhysics(),
      ),
      itemCount: provider.users.length,
      itemBuilder: (context, index) {
        final user = provider.users[index];
        return UserCard(
          user: user,
          onTap: () => _showUserDetails(user),
          onEdit: () => _showUserEdit(provider, user),
          onToggleStatus: () => _showStatusConfirmation(provider, user),
        );
      },
    ),
  );
}
```

## User Card Widget

Each user is displayed in a custom card component with key information:

```dart admin/presentation/widgets/user_management_widgets.dart theme={null}
class UserCard extends StatelessWidget {
  final Map<String, dynamic> user;
  final VoidCallback? onTap;
  final VoidCallback? onEdit;
  final VoidCallback? onToggleStatus;

  @override
  Widget build(BuildContext context) {
    final isActive = user['es_activo'] == 1;
    final tipoUsuario = user['tipo_usuario']?.toString() ?? 'cliente';
    
    return Card(
      child: ListTile(
        leading: CircleAvatar(
          backgroundImage: user['foto_perfil'] != null
              ? NetworkImage(user['foto_perfil'])
              : null,
          child: user['foto_perfil'] == null
              ? Icon(_getUserIcon(tipoUsuario))
              : null,
        ),
        title: Text('${user['nombre']} ${user['apellido']}'),
        subtitle: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(user['email'] ?? ''),
            Row(
              children: [
                _buildStatusBadge(isActive),
                _buildTypeBadge(tipoUsuario),
              ],
            ),
          ],
        ),
        trailing: PopupMenuButton(
          itemBuilder: (context) => [
            PopupMenuItem(
              child: Text('Ver detalles'),
              onTap: onTap,
            ),
            PopupMenuItem(
              child: Text('Editar'),
              onTap: onEdit,
            ),
            PopupMenuItem(
              child: Text(isActive ? 'Desactivar' : 'Activar'),
              onTap: onToggleStatus,
            ),
          ],
        ),
      ),
    );
  }
}
```

## User Details Sheet

View complete user information in a modal bottom sheet:

```dart admin/presentation/widgets/user_management_widgets.dart theme={null}
class UserDetailsSheet extends StatelessWidget {
  final Map<String, dynamic> user;

  @override
  Widget build(BuildContext context) {
    return DraggableScrollableSheet(
      initialChildSize: 0.7,
      minChildSize: 0.5,
      maxChildSize: 0.95,
      builder: (context, scrollController) {
        return Container(
          decoration: BoxDecoration(
            color: Theme.of(context).scaffoldBackgroundColor,
            borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
          ),
          child: SingleChildScrollView(
            controller: scrollController,
            child: Column(
              children: [
                _buildHeader(),
                _buildPersonalInfo(),
                _buildContactInfo(),
                _buildAccountInfo(),
                if (user['tipo_usuario'] == 'conductor')
                  _buildDriverInfo(),
                if (user['empresa_nombre'] != null)
                  _buildCompanyInfo(),
              ],
            ),
          ),
        );
      },
    );
  }
}
```

## Edit User Sheet

Modify user information through an edit form:

```dart admin/presentation/widgets/user_management_widgets.dart theme={null}
class UserEditSheet extends StatefulWidget {
  final Map<String, dynamic> user;
  final Function(String? nombre, String? apellido, String? telefono,
      String? tipoUsuario, int? empresaId, String? empresaNombre) onSave;

  @override
  State<UserEditSheet> createState() => _UserEditSheetState();
}

class _UserEditSheetState extends State<UserEditSheet> {
  late TextEditingController _nombreController;
  late TextEditingController _apellidoController;
  late TextEditingController _telefonoController;
  String? _selectedTipo;
  int? _selectedEmpresaId;

  @override
  void initState() {
    super.initState();
    _nombreController = TextEditingController(text: widget.user['nombre']);
    _apellidoController = TextEditingController(text: widget.user['apellido']);
    _telefonoController = TextEditingController(text: widget.user['telefono']);
    _selectedTipo = widget.user['tipo_usuario'];
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(24),
      child: Column(
        children: [
          TextField(
            controller: _nombreController,
            decoration: InputDecoration(labelText: 'Nombre'),
          ),
          TextField(
            controller: _apellidoController,
            decoration: InputDecoration(labelText: 'Apellido'),
          ),
          TextField(
            controller: _telefonoController,
            decoration: InputDecoration(labelText: 'Teléfono'),
          ),
          DropdownButtonFormField<String>(
            value: _selectedTipo,
            items: ['cliente', 'conductor', 'empresa']
                .map((tipo) => DropdownMenuItem(
                      value: tipo,
                      child: Text(tipo),
                    ))
                .toList(),
            onChanged: (value) => setState(() => _selectedTipo = value),
          ),
          ElevatedButton(
            onPressed: () {
              widget.onSave(
                _nombreController.text,
                _apellidoController.text,
                _telefonoController.text,
                _selectedTipo,
                _selectedEmpresaId,
                null,
              );
              Navigator.pop(context);
            },
            child: Text('Guardar Cambios'),
          ),
        ],
      ),
    );
  }
}
```

## Update User Implementation

```dart admin/presentation/providers/user_management_provider.dart theme={null}
Future<bool> updateUser({
  required int userId,
  String? nombre,
  String? apellido,
  String? telefono,
  String? tipoUsuario,
  int? empresaId,
  String? empresaNombre,
}) async {
  _setLoading(true);
  
  try {
    final result = await manageUserUseCase.updateUser(
      adminId: adminId,
      userId: userId,
      nombre: nombre,
      apellido: apellido,
      telefono: telefono,
      tipoUsuario: tipoUsuario,
      empresaId: empresaId,
    );

    return result.fold(
      (failure) {
        _setError('Error al actualizar: ${failure.toString()}');
        return false;
      },
      (success) {
        if (success) {
          // Update local list
          final index = _users.indexWhere((u) => u['id'] == userId);
          if (index != -1) {
            final updatedUser = Map<String, dynamic>.from(_users[index]);
            if (nombre != null) updatedUser['nombre'] = nombre;
            if (apellido != null) updatedUser['apellido'] = apellido;
            if (telefono != null) updatedUser['telefono'] = telefono;
            if (tipoUsuario != null) updatedUser['tipo_usuario'] = tipoUsuario;
            if (empresaId != null && empresaId > 0) {
              updatedUser['empresa_id'] = empresaId;
            }
            _users[index] = updatedUser;
            notifyListeners();
          }
        }
        _setLoading(false);
        return success;
      },
    );
  } catch (e) {
    _setError('Error inesperado: $e');
    return false;
  }
}
```

## Toggle User Status

Activate or deactivate user accounts:

```dart admin/presentation/screens/users_management_screen.dart theme={null}
void _showStatusConfirmation(AdminUserManagementProvider provider, Map<String, dynamic> user) {
  final isActivating = user['es_activo'] == 0;
  final action = isActivating ? 'activar' : 'desactivar';
  final color = isActivating ? AppColors.success : AppColors.warning;

  showDialog(
    context: context,
    builder: (context) => AlertDialog(
      title: Row(
        children: [
          Container(
            padding: const EdgeInsets.all(8),
            decoration: BoxDecoration(
              color: color.withValues(alpha: 0.1),
              borderRadius: BorderRadius.circular(8),
            ),
            child: Icon(
              isActivating ? Icons.play_circle_outline : Icons.pause_circle_outline,
              color: color,
            ),
          ),
          Text('${action[0].toUpperCase()}${action.substring(1)} Usuario'),
        ],
      ),
      content: Text('¿Estás seguro de que deseas $action a "${user['nombre']}"?'),
      actions: [
        TextButton(
          onPressed: () => Navigator.pop(context),
          child: const Text('Cancelar'),
        ),
        ElevatedButton(
          onPressed: () async {
            Navigator.pop(context);
            await provider.toggleUserStatus(user['id'], !isActivating);
          },
          style: ElevatedButton.styleFrom(backgroundColor: color),
          child: Text(isActivating ? 'Activar' : 'Desactivar'),
        ),
      ],
    ),
  );
}
```

## Status Toggle Implementation

```dart admin/presentation/providers/user_management_provider.dart theme={null}
Future<bool> toggleUserStatus(int userId, bool currentStatus) async {
  final result = await manageUserUseCase.updateUser(
    adminId: adminId,
    userId: userId,
    esActivo: !currentStatus,
  );

  return result.fold(
    (failure) {
      _setError("Error al actualizar estado");
      return false;
    },
    (success) {
      if (success) {
        // Update local list
        final index = _users.indexWhere((u) => u['id'] == userId);
        if (index != -1) {
          _users[index]['es_activo'] = !currentStatus ? 1 : 0;
          notifyListeners();
        }
      }
      return success;
    },
  );
}
```

## Empty State

```dart admin/presentation/screens/users_management_screen.dart theme={null}
Widget _buildEmptyState() {
  return Center(
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Container(
          padding: const EdgeInsets.all(20),
          decoration: BoxDecoration(
            color: AppColors.primary.withValues(alpha: 0.1),
            shape: BoxShape.circle,
          ),
          child: const Icon(
            Icons.people_outline_rounded,
            color: AppColors.primary,
            size: 48,
          ),
        ),
        const SizedBox(height: 16),
        Text('No hay usuarios'),
        Text('No se encontraron usuarios con los filtros actuales'),
      ],
    ),
  );
}
```

<Note>
  All changes to user data are automatically reflected in the UI without requiring a page refresh.
</Note>

## Best Practices

<Accordion title="Use Filters Effectively">
  Combine user type filters with active/inactive toggle to quickly find specific user groups.
</Accordion>

<Accordion title="Verify Before Deactivating">
  Always review user details before deactivating accounts to avoid accidental disruptions.
</Accordion>

<Accordion title="Assign Companies Properly">
  For drivers, ensure they're assigned to the correct transport company for proper commission tracking.
</Accordion>

<Accordion title="Monitor Inactive Accounts">
  Regularly review inactive accounts to identify issues or re-engage dormant users.
</Accordion>

## Related Features

<CardGroup cols={3}>
  <Card title="Driver Management" icon="id-card" href="/admin/driver-management">
    Verify and approve drivers
  </Card>

  <Card title="Company Management" icon="building" href="/admin/company-management">
    Manage transport companies
  </Card>

  <Card title="Audit Logs" icon="list" href="/admin/audit-logs">
    Track user changes
  </Card>
</CardGroup>
