Skip to main content

Overview

The Admin Dashboard provides a comprehensive, real-time view of your platform’s performance with interactive metrics, charts, and activity feeds. Admin Dashboard

Dashboard Components

Welcome Section

The dashboard greets administrators with a personalized welcome message that adapts based on time of day:
admin/presentation/screens/admin_dashboard_tab.dart
Widget _buildWelcomeSection(String adminName) {
  final hour = DateTime.now().hour;
  String greeting = 'Buenos días';
  IconData greetingIcon = Icons.wb_sunny_rounded;

  if (hour >= 12 && hour < 18) {
    greeting = 'Buenas tardes';
    greetingIcon = Icons.wb_cloudy_rounded;
  } else if (hour >= 18) {
    greeting = 'Buenas noches';
    greetingIcon = Icons.nightlight_round;
  }

  return AccentGlassContainer(
    accentColor: AppColors.primary,
    child: Row(
      children: [
        Container(
          decoration: BoxDecoration(
            color: AppColors.primary,
            borderRadius: BorderRadius.circular(18),
          ),
          child: Icon(greetingIcon, color: Colors.white, size: 30),
        ),
        Text(adminName, style: TextStyle(fontSize: 24, fontWeight: FontWeight.w800)),
      ],
    ),
  );
}

Real-Time Metrics

The dashboard displays four key metric cards, all clickable for detailed views:

Total Users

Main Value: Total registered usersSubtitle: Active users countClick Action: Navigate to User Management

Trip Requests

Main Value: Total trip requestsSubtitle: Requests todayClick Action: Navigate to Statistics tab

Platform Earnings

Main Value: Total earningsSubtitle: Today’s earningsClick Action: Navigate to Statistics tab

Pending Reports

Main Value: Pending reports countSubtitle: Requires attentionClick Action: Navigate to Audit Logs

Metric Card Implementation

admin/presentation/screens/admin_dashboard_tab.dart
Widget _buildStatsGrid() {
  final users = _dashboardData?['usuarios'] ?? {};
  final solicitudes = _dashboardData?['solicitudes'] ?? {};
  final ingresos = _dashboardData?['ingresos'] ?? {};
  final reportes = _dashboardData?['reportes'] ?? {};

  return GridView.count(
    crossAxisCount: 2,
    crossAxisSpacing: 14,
    mainAxisSpacing: 14,
    children: [
      StatCard(
        title: 'Usuarios',
        value: (users['total_usuarios'] ?? 0).toString(),
        subtitle: 'Activos: ${users['usuarios_activos'] ?? 0}',
        icon: Icons.people_rounded,
        color: AppColors.blue600,
        onTap: () {
          Navigator.pushNamed(context, RouteNames.adminUsers,
              arguments: {'admin_id': adminId, 'admin_user': adminUser});
        },
      ),
      // Additional cards...
    ],
  );
}

Dashboard Data Structure

The dashboard receives comprehensive statistics from the backend:
{
  "usuarios": {
    "total_usuarios": 1250,
    "total_clientes": 980,
    "total_conductores": 270,
    "usuarios_activos": 1100,
    "registros_hoy": 45
  },
  "solicitudes": {
    "total_solicitudes": 5840,
    "completadas": 5200,
    "canceladas": 540,
    "en_proceso": 100,
    "solicitudes_hoy": 120
  },
  "ingresos": {
    "ingresos_totales": 125000000,
    "ingresos_hoy": 2500000
  },
  "reportes": {
    "reportes_pendientes": 12
  },
  "actividades_recientes": [
    {
      "tipo": "USER_REGISTER",
      "descripcion": "Nuevo usuario registrado",
      "nombre": "Juan",
      "apellido": "Pérez",
      "fecha_creacion": "2026-03-05T10:30:00Z"
    }
  ],
  "registros_ultimos_7_dias": [
    {"fecha": "2026-02-28", "cantidad": 35},
    {"fecha": "2026-03-01", "cantidad": 42}
  ]
}

Platform Earnings

A dedicated section shows platform commission earnings from transport companies:
admin/presentation/screens/admin_dashboard_tab.dart
Widget _buildPlatformEarningsCard() {
  return ActionCard(
    title: 'Ganancias Plataforma',
    subtitle: 'Ver cuentas por cobrar de empresas',
    icon: Icons.account_balance_rounded,
    color: AppColors.primary,
    onTap: () {
      Navigator.push(
        context,
        MaterialPageRoute(
          builder: (_) => PlatformEarningsScreen(adminId: adminId),
        ),
      );
    },
  );
}

Recent Activity Feed

The dashboard displays the latest system activities with color-coded icons:
Icon: Login roundedColor: Green (#11998e)Example: “Usuario inició sesión”

Activity Item Implementation

admin/presentation/screens/admin_dashboard_tab.dart
Widget _buildActivityItem(Map<String, dynamic> actividad) {
  final tipo = actividad['tipo']?.toString().toUpperCase() ?? '';
  Color iconColor = AppColors.primary;
  IconData iconData = Icons.notifications_active_rounded;

  if (tipo.contains('LOGIN')) {
    iconColor = AppColors.success;
    iconData = Icons.login_rounded;
  } else if (tipo.contains('REGISTER')) {
    iconColor = AppColors.accent;
    iconData = Icons.person_add_rounded;
  } else if (tipo.contains('ERROR')) {
    iconColor = AppColors.error;
    iconData = Icons.error_outline_rounded;
  }

  return ListTile(
    leading: Container(
      decoration: BoxDecoration(
        color: iconColor.withValues(alpha: 0.12),
        borderRadius: BorderRadius.circular(14),
      ),
      child: Icon(iconData, color: iconColor),
    ),
    title: Text(actividad['descripcion'] ?? 'Sin descripción'),
    subtitle: Text('${actividad['nombre']}${_formatDate(actividad['fecha_creacion'])}'),
  );
}

Time Formatting

Activities are displayed with human-readable relative timestamps:
admin/presentation/screens/admin_dashboard_tab.dart
String _formatDate(String? dateStr) {
  if (dateStr == null) return '';
  try {
    final date = DateTime.parse(dateStr);
    final now = DateTime.now();
    final diff = now.difference(date);

    if (diff.inMinutes < 1) return 'Ahora';
    if (diff.inMinutes < 60) return 'Hace ${diff.inMinutes}m';
    if (diff.inHours < 24) return 'Hace ${diff.inHours}h';
    if (diff.inDays < 7) return 'Hace ${diff.inDays}d';
    return '${date.day}/${date.month}/${date.year}';
  } catch (e) {
    return dateStr;
  }
}

Number Formatting

Large numbers are automatically formatted for readability:
admin/presentation/screens/admin_dashboard_tab.dart
String _formatNumber(dynamic value) {
  if (value == null) return '0';
  final num = double.tryParse(value.toString()) ?? 0;
  if (num >= 1000000) {
    return '${(num / 1000000).toStringAsFixed(1)}M';
  } else if (num >= 1000) {
    return '${(num / 1000).toStringAsFixed(1)}K';
  }
  return num.toStringAsFixed(0);
}
Examples:
  • 1,250 → “1.3K”
  • 125,000 → “125.0K”
  • 2,500,000 → “2.5M”

Loading States

The dashboard implements shimmer loading for a smooth user experience:
if (_isLoading) {
  return const DashboardShimmer();
}
All dashboard data automatically refreshes when you pull down on the screen or navigate back to the Dashboard tab.

Refresh Functionality

1

Pull to Refresh

Swipe down on the dashboard to manually refresh all metrics
2

Auto Refresh

Dashboard data refreshes when navigating back from other sections
3

Loading State

Shimmer animation displays during data fetch
Dashboard cards provide quick navigation:
CardDestinationData Passed
UsersUser Management Screenadmin_id, admin_user
RequestsStatistics TabIndex 2
EarningsStatistics TabIndex 2
ReportsAudit Logs Screenadmin_id

Best Practices

Check the dashboard daily to stay informed about platform activity, user growth, and pending tasks.
Regularly review recent activities to catch unusual patterns or errors early.
Monitor key metrics like active users, completed trips, and earnings trends.
Use clickable metric cards for quick navigation to relevant management sections.

Statistics

Detailed analytics and charts

User Management

Manage platform users

Audit Logs

View all system activities

Build docs developers (and LLMs) love