Actualizacion de mejoras

This commit is contained in:
2026-05-23 08:36:15 -06:00
parent ebce0badde
commit 8fe3665ffb
11 changed files with 738 additions and 291 deletions

View File

@@ -52,34 +52,63 @@ class _ManageConductorsScreenState extends State<ManageConductorsScreen> {
if (existing != null)
SwitchListTile(value: activo, dense: true,
title: Text(activo ? 'Conductor Activo' : 'Conductor Inactivo',
style: TextStyle(color: activo ? AppColors.verdeAdmin : AppColors.rojoError,
style: TextStyle(color: activo ? AppColors.guindaPrimary : AppColors.rojoError,
fontWeight: FontWeight.bold)),
activeColor: AppColors.verdeAdmin,
activeColor: AppColors.guindaPrimary,
onChanged: (v) => setSt(() => activo = v)),
])),
actions: [
TextButton(onPressed: () => Navigator.pop(ctx), child: const Text('Cancelar')),
ElevatedButton(
style: ElevatedButton.styleFrom(backgroundColor: AppColors.verdeAdmin,
style: ElevatedButton.styleFrom(backgroundColor: AppColors.guindaPrimary,
foregroundColor: Colors.white),
onPressed: () async {
if (nombreCtrl.text.trim().isEmpty || emailCtrl.text.trim().isEmpty) return;
if (existing == null) {
if (passCtrl.text.length < 6) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('La contrasena debe tener al menos 6 caracteres'),
backgroundColor: AppColors.rojoError));
return;
}
await DbHelper.insertConductor(nombreCtrl.text.trim(),
emailCtrl.text.trim().toLowerCase(), passCtrl.text);
} else {
await DbHelper.updateConductor(existing['id'], nombreCtrl.text.trim(),
emailCtrl.text.trim().toLowerCase());
await DbHelper.updateConductorMeta(existing['id'], activo, notasCtrl.text.trim());
if (nombreCtrl.text.trim().isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('Ingresa el nombre del conductor'),
backgroundColor: AppColors.rojoError));
return;
}
if (emailCtrl.text.trim().isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('Ingresa el correo electronico'),
backgroundColor: AppColors.rojoError));
return;
}
try {
if (existing == null) {
if (passCtrl.text.length < 6) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('La contrasena debe tener al menos 6 caracteres'),
backgroundColor: AppColors.rojoError));
return;
}
await DbHelper.insertConductor(
nombreCtrl.text.trim(),
emailCtrl.text.trim().toLowerCase(),
passCtrl.text);
if (ctx.mounted) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('Conductor creado correctamente'),
backgroundColor: AppColors.verdeExito));
}
} else {
await DbHelper.updateConductor(existing['id'], nombreCtrl.text.trim(),
emailCtrl.text.trim().toLowerCase());
await DbHelper.updateConductorMeta(
existing['id'], activo, notasCtrl.text.trim());
}
if (ctx.mounted) Navigator.pop(ctx);
await _load();
} catch (e) {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(e.toString().contains('UNIQUE')
? 'Ese correo ya está registrado'
: 'Error: ${e.toString()}'),
backgroundColor: AppColors.rojoError));
}
}
if (ctx.mounted) Navigator.pop(ctx);
await _load();
},
child: Text(existing == null ? 'Crear' : 'Guardar')),
])));
@@ -89,7 +118,7 @@ class _ManageConductorsScreenState extends State<ManageConductorsScreen> {
Widget build(BuildContext context) => Scaffold(
backgroundColor: AppColors.grisFondo,
appBar: AppBar(
backgroundColor: AppColors.verdeAdmin, foregroundColor: Colors.white,
backgroundColor: AppColors.guindaPrimary, foregroundColor: Colors.white,
title: Text('Conductores (${_conductores.length})'),
bottom: PreferredSize(preferredSize: const Size.fromHeight(4),
child: Container(height: 4, color: AppColors.dorado)),
@@ -110,7 +139,7 @@ class _ManageConductorsScreenState extends State<ManageConductorsScreen> {
style: TextStyle(color: AppColors.grisTexto)),
const SizedBox(height: 16),
ElevatedButton.icon(
style: ElevatedButton.styleFrom(backgroundColor: AppColors.verdeAdmin,
style: ElevatedButton.styleFrom(backgroundColor: AppColors.guindaPrimary,
foregroundColor: Colors.white),
onPressed: () => _showFormDialog(),
icon: const Icon(Icons.add), label: const Text('Agregar primer conductor')),
@@ -126,17 +155,17 @@ class _ManageConductorsScreenState extends State<ManageConductorsScreen> {
margin: const EdgeInsets.only(bottom: 10),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10),
side: BorderSide(color: activo
? AppColors.verdeAdmin.withOpacity(0.3)
? AppColors.guindaPrimary.withOpacity(0.3)
: AppColors.rojoError.withOpacity(0.3))),
child: Padding(padding: const EdgeInsets.all(14), child: Column(
crossAxisAlignment: CrossAxisAlignment.start, children: [
Row(children: [
CircleAvatar(radius: 22,
backgroundColor: activo
? AppColors.verdeAdmin.withOpacity(0.15)
? AppColors.guindaPrimary.withOpacity(0.15)
: Colors.grey.shade200,
child: Icon(Icons.person,
color: activo ? AppColors.verdeAdmin : AppColors.grisTexto, size: 24)),
color: activo ? AppColors.guindaPrimary : AppColors.grisTexto, size: 24)),
const SizedBox(width: 12),
Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(c['nombre'] ?? '', style: const TextStyle(
@@ -146,12 +175,12 @@ class _ManageConductorsScreenState extends State<ManageConductorsScreen> {
])),
Container(padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
decoration: BoxDecoration(
color: activo ? AppColors.verdeAdmin.withOpacity(0.1)
color: activo ? AppColors.guindaPrimary.withOpacity(0.1)
: AppColors.rojoError.withOpacity(0.1),
borderRadius: BorderRadius.circular(10)),
child: Text(activo ? 'Activo' : 'Inactivo',
style: TextStyle(fontSize: 11, fontWeight: FontWeight.bold,
color: activo ? AppColors.verdeAdmin : AppColors.rojoError))),
color: activo ? AppColors.guindaPrimary : AppColors.rojoError))),
IconButton(icon: const Icon(Icons.edit_outlined, size: 18),
onPressed: () => _showFormDialog(existing: c)),
]),