Files
home-control/lib/screens/dashboard_screen.dart
2026-06-14 15:03:29 -04:00

143 lines
5.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:intl/intl.dart';
import '../providers/servicio_provider.dart';
import '../providers/factura_provider.dart';
import '../providers/configuracion_provider.dart';
import '../widgets/stat_card.dart';
import 'servicios_screen.dart';
import 'facturas_screen.dart';
import 'calendario_screen.dart';
import 'estadisticas_screen.dart';
import 'configuracion_screen.dart';
import 'crear_factura_screen.dart';
class DashboardScreen extends StatefulWidget {
const DashboardScreen({super.key});
@override
State<DashboardScreen> createState() => _DashboardScreenState();
}
class _DashboardScreenState extends State<DashboardScreen> {
@override
void initState() {
super.initState();
_cargarDatos();
}
void _cargarDatos() {
context.read<ServicioProvider>().cargarServicios();
context.read<FacturaProvider>().cargarFacturas();
}
@override
Widget build(BuildContext context) {
final facturaProv = context.watch<FacturaProvider>();
final servicioProv = context.watch<ServicioProvider>();
final configProv = context.watch<ConfiguracionProvider>();
final moneda = configProv.config?.moneda ?? 'USD';
final symbol = moneda == 'USD' ? '\$' : moneda == 'EUR' ? '' : moneda == 'MXN' ? 'MX\$' : '\$';
final pendientes = facturaProv.facturas.where((f) => f.estado == 'Pendiente').length;
final vencidas = facturaProv.facturasVencidas.length;
return Scaffold(
appBar: AppBar(title: const Text('HogarControl'), centerTitle: true, actions: [
IconButton(icon: const Icon(Icons.settings), onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const ConfiguracionScreen()))),
]),
body: RefreshIndicator(
onRefresh: () async => _cargarDatos(),
child: ListView(
padding: const EdgeInsets.all(16),
children: [
Row(
children: [
Expanded(child: StatCard(
title: 'Pendientes',
value: '$pendientes',
icon: Icons.pending_actions,
color: Colors.orange,
)),
const SizedBox(width: 12),
Expanded(child: StatCard(
title: 'Vencidas',
value: '$vencidas',
icon: Icons.warning_rounded,
color: Colors.red,
)),
],
),
const SizedBox(height: 12),
Row(
children: [
Expanded(child: StatCard(
title: 'Pagadas este mes',
value: facturaProv.facturas.where((f) => f.estado == 'Pagada').length.toString(),
icon: Icons.check_circle,
color: Colors.green,
)),
const SizedBox(width: 12),
Expanded(child: StatCard(
title: 'Total gastado',
value: '$symbol${NumberFormat('#,##0.00').format(facturaProv.facturas.where((f) => f.estado == 'Pagada').fold(0.0, (sum, f) => sum + f.monto))}',
icon: Icons.attach_money,
color: Colors.blue,
)),
],
),
const SizedBox(height: 20),
Text('Próximos vencimientos', style: Theme.of(context).textTheme.titleMedium),
const SizedBox(height: 8),
...facturaProv.facturas
.where((f) => f.estado == 'Pendiente')
.take(5)
.map((f) {
final servicio = servicioProv.servicios.where((s) => s.id == f.servicioId).firstOrNull;
return Card(
child: ListTile(
leading: CircleAvatar(
backgroundColor: Color(servicio?.color ?? 0xFF6200EE),
child: Text(servicio?.nombre.substring(0, 2).toUpperCase() ?? '??',
style: const TextStyle(color: Colors.white, fontSize: 12)),
),
title: Text(servicio?.nombre ?? 'Desconocido'),
subtitle: Text('Ven: ${f.fechaVencimiento} $symbol${NumberFormat('#,##0.00').format(f.monto)}'),
trailing: TextButton(
onPressed: () => facturaProv.marcarPagada(f.id!),
child: const Text('Pagar'),
),
),
);
}),
],
),
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const CrearFacturaScreen())).then((_) => _cargarDatos()),
icon: const Icon(Icons.add),
label: const Text('Nueva factura'),
),
bottomNavigationBar: NavigationBar(
selectedIndex: 0,
onDestinationSelected: (i) {
switch (i) {
case 0: break;
case 1: Navigator.push(context, MaterialPageRoute(builder: (_) => const ServiciosScreen()));
case 2: Navigator.push(context, MaterialPageRoute(builder: (_) => const FacturasScreen()));
case 3: Navigator.push(context, MaterialPageRoute(builder: (_) => const CalendarioScreen()));
case 4: Navigator.push(context, MaterialPageRoute(builder: (_) => const EstadisticasScreen()));
}
},
destinations: const [
NavigationDestination(icon: Icon(Icons.dashboard), label: 'Dashboard'),
NavigationDestination(icon: Icon(Icons.electrical_services), label: 'Servicios'),
NavigationDestination(icon: Icon(Icons.receipt_long), label: 'Facturas'),
NavigationDestination(icon: Icon(Icons.calendar_month), label: 'Calendario'),
NavigationDestination(icon: Icon(Icons.bar_chart), label: 'Stats'),
],
),
);
}
}