Files
hackathon-heavy-gears-7cc00…/lib/tarjetaeta.dart
2026-05-23 05:54:34 -06:00

196 lines
5.6 KiB
Dart

import 'package:flutter/material.dart';
import 'camion_estado.dart';
class TarjetaEtaWidget extends StatefulWidget {
const TarjetaEtaWidget({super.key});
@override
State<TarjetaEtaWidget> createState() => _TarjetaEtaWidgetState();
}
class _TarjetaEtaWidgetState extends State<TarjetaEtaWidget> {
@override
void initState() {
super.initState();
// Escucha cambios del estado global
camionEstado.addListener(_actualizar);
}
void _actualizar() {
if (mounted) setState(() {});
}
@override
void dispose() {
camionEstado.removeListener(_actualizar);
super.dispose();
}
// Color según etapa
Color _colorEstado() {
final id = camionEstado.positionId;
if (id <= 1) return Colors.grey;
if (id <= 3) return Colors.blue;
if (id <= 5) return Colors.orange;
if (id == 6) return Colors.green;
return Colors.grey;
}
// Icono según etapa
IconData _iconoEstado() {
final id = camionEstado.positionId;
if (id <= 1) return Icons.schedule;
if (id <= 3) return Icons.local_shipping;
if (id <= 5) return Icons.directions_run;
if (id == 6) return Icons.check_circle;
return Icons.done_all;
}
@override
Widget build(BuildContext context) {
final id = camionEstado.positionId;
final eta = CamionEstado.etaInfo[id]!;
final etapa = CamionEstado.etapas[id]!;
final color = _colorEstado();
final minutos = eta['minutos'] as int;
final label = eta['label'] as String;
return Card(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: [
// Icono animado según estado
Icon(
_iconoEstado(),
size: 80,
color: color,
),
const SizedBox(height: 12),
const Text(
'Camión de Recolección',
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
// Etapa actual
Text(
etapa,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
color: color,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 8),
// Hora estimada
if (id > 1 && id < 7)
Text(
'Llegará entre ${eta['horaInicio']} y ${eta['horaFin']}',
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 14, color: Colors.grey),
),
const SizedBox(height: 16),
// Barra de progreso
ClipRRect(
borderRadius: BorderRadius.circular(8),
child: LinearProgressIndicator(
value: id / 8,
minHeight: 10,
backgroundColor: Colors.grey[200],
valueColor: AlwaysStoppedAnimation<Color>(color),
),
),
const SizedBox(height: 12),
// Badge de minutos
Container(
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 12,
),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(15),
border: Border.all(color: color.withOpacity(0.3)),
),
child: Text(
minutos > 0
? 'Llega en aproximadamente $minutos minutos'
: label,
textAlign: TextAlign.center,
style: TextStyle(
color: color,
fontWeight: FontWeight.bold,
fontSize: 14,
),
),
),
const SizedBox(height: 16),
// Botones iniciar / reiniciar
Row(
children: [
Expanded(
child: ElevatedButton.icon(
style: ElevatedButton.styleFrom(
backgroundColor: camionEstado.corriendo
? Colors.grey
: Colors.green,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
onPressed: camionEstado.corriendo
? null
: camionEstado.iniciarTimer,
icon: const Icon(Icons.play_arrow),
label: const Text('Iniciar'),
),
),
const SizedBox(width: 12),
Expanded(
child: OutlinedButton.icon(
style: OutlinedButton.styleFrom(
foregroundColor: Colors.green,
side: const BorderSide(color: Colors.green),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
onPressed: camionEstado.reiniciar,
icon: const Icon(Icons.refresh),
label: const Text('Reiniciar'),
),
),
],
),
],
),
),
);
}
}