Skip to main content

Overview

The Statistics screen provides detailed analytics with interactive charts, graphs, and comprehensive reporting tools for data-driven decision making.

Statistics Screen

Access advanced analytics from the admin panel’s Statistics tab:
admin/presentation/screens/statistics_screen.dart
class StatisticsScreen extends StatefulWidget {
  final int adminId;

  const StatisticsScreen({
    super.key,
    required this.adminId,
  });
}

Time Period Selection

Filter reports by customizable time periods:
View metrics for the last week - ideal for short-term trends

Period Selector Implementation

admin/presentation/screens/statistics_screen.dart
Widget _buildPeriodSelector() {
  return Container(
    decoration: BoxDecoration(
      color: _surfaceColor.withValues(alpha: 0.8),
      borderRadius: BorderRadius.circular(16),
    ),
    child: Row(
      children: [
        _buildPeriodButton('7 días', '7d'),
        _buildPeriodButton('30 días', '30d'),
        _buildPeriodButton('Todo', 'all'),
      ],
    ),
  );
}

Widget _buildPeriodButton(String label, String value) {
  final isSelected = _selectedPeriod == value;
  return Expanded(
    child: GestureDetector(
      onTap: () {
        setState(() => _selectedPeriod = value);
        _loadStats();
      },
      child: Container(
        decoration: BoxDecoration(
          color: isSelected ? _primaryColor : Colors.transparent,
          borderRadius: BorderRadius.circular(12),
        ),
        child: Text(label),
      ),
    ),
  );
}
Visualize new user registrations over time with an interactive line chart: Registration Trends

Chart Data Structure

{
  "registros_ultimos_7_dias": [
    {"fecha": "2026-02-28", "cantidad": 35},
    {"fecha": "2026-03-01", "cantidad": 42},
    {"fecha": "2026-03-02", "cantidad": 38},
    {"fecha": "2026-03-03", "cantidad": 51},
    {"fecha": "2026-03-04", "cantidad": 47},
    {"fecha": "2026-03-05", "cantidad": 55},
    {"fecha": "2026-03-06", "cantidad": 49}
  ]
}

Line Chart Implementation

admin/presentation/screens/statistics_screen.dart
Widget _buildRegistrosChart() {
  final registros = _stats?['registros_ultimos_7_dias'] ?? [];
  
  return Container(
    padding: const EdgeInsets.all(24),
    child: Column(
      children: [
        Text('Registros Recientes', style: TextStyle(fontSize: 18)),
        SizedBox(
          height: 200,
          child: LineChart(
            LineChartData(
              gridData: FlGridData(show: true, drawVerticalLine: false),
              lineBarsData: [
                LineChartBarData(
                  spots: _getChartSpots(registros),
                  isCurved: true,
                  color: _primaryColor,
                  barWidth: 3,
                  dotData: FlDotData(show: true),
                  belowBarData: BarAreaData(
                    show: true,
                    color: _primaryColor.withValues(alpha: 0.1),
                  ),
                ),
              ],
            ),
          ),
        ),
      ],
    ),
  );
}

List<FlSpot> _getChartSpots(List<dynamic> registros) {
  return List.generate(
    registros.length,
    (index) {
      final cantidad = int.tryParse(registros[index]['cantidad']?.toString() ?? '0') ?? 0;
      return FlSpot(index.toDouble(), cantidad.toDouble());
    },
  );
}

Metrics Grid

A comprehensive grid displaying key platform statistics:

Total Users

All registered users on the platform

Total Clients

Passenger accounts (ride requesters)

Total Drivers

Active driver accounts

Trip Requests

All trip requests (completed, cancelled, in progress)

Stat Card Implementation

admin/presentation/screens/statistics_screen.dart
Widget _buildStatsGrid() {
  final users = _stats?['usuarios'] ?? {};
  final solicitudes = _stats?['solicitudes'] ?? {};

  return GridView.count(
    crossAxisCount: 2,
    crossAxisSpacing: 16,
    mainAxisSpacing: 16,
    childAspectRatio: 1.5,
    children: [
      _buildStatCard(
        'Total Usuarios',
        users['total_usuarios']?.toString() ?? '0',
        Icons.people_rounded,
        _statCardColor1,
      ),
      _buildStatCard(
        'Clientes',
        users['total_clientes']?.toString() ?? '0',
        Icons.person_rounded,
        _statCardColor2,
      ),
      _buildStatCard(
        'Conductores',
        users['total_conductores']?.toString() ?? '0',
        Icons.local_taxi_rounded,
        _statCardColor3,
      ),
      _buildStatCard(
        'Solicitudes',
        solicitudes['total_solicitudes']?.toString() ?? '0',
        Icons.receipt_long_rounded,
        _statCardColor4,
      ),
    ],
  );
}

Trip Distribution Chart

Interactive pie chart showing the breakdown of trip statuses: Trip Distribution

Distribution Data

{
  "solicitudes": {
    "completadas": 5200,
    "canceladas": 540,
    "en_proceso": 100
  }
}

Pie Chart Implementation

admin/presentation/screens/statistics_screen.dart
Widget _buildDistributionChart() {
  final solicitudes = _stats?['solicitudes'] ?? {};
  final completadas = int.tryParse(solicitudes['completadas']?.toString() ?? '0') ?? 0;
  final canceladas = int.tryParse(solicitudes['canceladas']?.toString() ?? '0') ?? 0;
  final enProceso = int.tryParse(solicitudes['en_proceso']?.toString() ?? '0') ?? 0;
  final total = completadas + canceladas + enProceso;

  return PieChart(
    PieChartData(
      sectionsSpace: 2,
      centerSpaceRadius: 40,
      sections: [
        PieChartSectionData(
          value: completadas.toDouble(),
          title: '${((completadas / total) * 100).toStringAsFixed(0)}%',
          color: _statCardColor2, // Green
          radius: 50,
        ),
        PieChartSectionData(
          value: canceladas.toDouble(),
          title: '${((canceladas / total) * 100).toStringAsFixed(0)}%',
          color: _statCardColor3, // Red
          radius: 50,
        ),
        PieChartSectionData(
          value: enProceso.toDouble(),
          title: '${((enProceso / total) * 100).toStringAsFixed(0)}%',
          color: _primaryColor, // Yellow
          radius: 50,
        ),
      ],
    ),
  );
}

Chart Legend

admin/presentation/screens/statistics_screen.dart
Widget _buildLegendItem(String label, int value, Color color) {
  return Row(
    children: [
      Container(
        width: 12,
        height: 12,
        decoration: BoxDecoration(
          color: color,
          borderRadius: BorderRadius.circular(3),
        ),
      ),
      const SizedBox(width: 8),
      Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(label, style: TextStyle(fontSize: 11)),
          Text(value.toString(), style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
        ],
      ),
    ],
  );
}

Chart Color Coding

StatusColorHex CodeMeaning
CompletadasGreen#11998eSuccessfully finished trips
CanceladasRed#f5576cCancelled or failed trips
En ProcesoYellow#FFFF00Currently active trips

Data Refresh

1

Pull to Refresh

Swipe down to manually reload all statistics
2

Period Change

Changing the time period automatically refreshes data
3

Navigation Refresh

Statistics reload when navigating back to the tab

Loading States

The statistics screen implements shimmer loading for all chart components:
admin/presentation/screens/statistics_screen.dart
Widget _buildShimmerLoading() {
  return SafeArea(
    child: SingleChildScrollView(
      padding: const EdgeInsets.all(20),
      child: Column(
        children: [
          _buildShimmerBox(height: 60),
          _buildShimmerBox(height: 300),
          GridView.count(
            shrinkWrap: true,
            crossAxisCount: 2,
            children: List.generate(4, (_) => _buildShimmerBox(height: 100)),
          ),
          _buildShimmerBox(height: 200),
        ],
      ),
    ),
  );
}

Empty State Handling

admin/presentation/screens/statistics_screen.dart
Widget _buildEmptyState() {
  return Container(
    padding: const EdgeInsets.all(40),
    child: Column(
      children: [
        Icon(Icons.bar_chart_rounded, color: Colors.white30, size: 40),
        const SizedBox(height: 16),
        Text('No hay datos disponibles'),
        Text('Las estadísticas aparecerán aquí'),
      ],
    ),
  );
}

Animation System

Smooth animations enhance the user experience:
admin/presentation/screens/statistics_screen.dart
void _setupAnimations() {
  _animationController = AnimationController(
    vsync: this,
    duration: const Duration(milliseconds: 600),
  );

  _fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
    CurvedAnimation(parent: _animationController, curve: Curves.easeOut),
  );

  _slideAnimation = Tween<Offset>(
    begin: const Offset(0, 0.1),
    end: Offset.zero,
  ).animate(CurvedAnimation(
    parent: _animationController, 
    curve: Curves.easeOutCubic,
  ));
}
All charts are interactive - tap on data points for detailed information.

Export Options

Export functionality is planned for future releases. Currently, you can take screenshots of charts for reporting.

Best Practices

Check statistics weekly to identify trends in user growth and trip activity.
Use different time periods to compare performance across weeks, months, and overall.
Monitor the cancellation rate - a high percentage may indicate service issues.
Use the registration chart to measure marketing campaign effectiveness.

Dashboard

Quick metrics overview

Audit Logs

Detailed activity tracking

Trip Monitoring

Real-time trip tracking

Build docs developers (and LLMs) love