107 lines
5.7 KiB
Dart
107 lines
5.7 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import '../core/app_colors.dart';
|
|
import '../services/auth_service.dart';
|
|
|
|
class LoginScreen extends StatefulWidget {
|
|
const LoginScreen({super.key});
|
|
@override State<LoginScreen> createState() => _LoginScreenState();
|
|
}
|
|
|
|
class _LoginScreenState extends State<LoginScreen> {
|
|
final _emailCtrl = TextEditingController();
|
|
final _passCtrl = TextEditingController();
|
|
bool _loading = false, _obscure = true;
|
|
|
|
Future<void> _login() async {
|
|
if (_emailCtrl.text.isEmpty || _passCtrl.text.isEmpty) {
|
|
_snack('Llena todos los campos', isError: true); return;
|
|
}
|
|
setState(() => _loading = true);
|
|
final err = await context.read<AuthService>().login(_emailCtrl.text, _passCtrl.text);
|
|
if (!mounted) return;
|
|
setState(() => _loading = false);
|
|
if (err != null) { _snack(err, isError: true); return; }
|
|
final rol = context.read<AuthService>().rol;
|
|
switch (rol) {
|
|
case 'ADMINISTRADOR': Navigator.pushReplacementNamed(context, '/admin'); break;
|
|
case 'CONDUCTOR': Navigator.pushReplacementNamed(context, '/driver'); break;
|
|
default: Navigator.pushReplacementNamed(context, '/home'); break;
|
|
}
|
|
}
|
|
|
|
void _snack(String msg, {bool isError = false}) => ScaffoldMessenger.of(context)
|
|
.showSnackBar(SnackBar(content:Text(msg),
|
|
backgroundColor: isError ? AppColors.rojoError : AppColors.verdeExito));
|
|
|
|
@override
|
|
Widget build(BuildContext context) => Scaffold(
|
|
backgroundColor: AppColors.grisFondo,
|
|
body: SingleChildScrollView(child: Column(children: [
|
|
Container(width:double.infinity, color:AppColors.guindaPrimary,
|
|
padding:const EdgeInsets.only(top:60,bottom:28),
|
|
child:Column(children:[
|
|
Container(width:84,height:84,
|
|
decoration:BoxDecoration(color:Colors.white12,shape:BoxShape.circle,
|
|
border:Border.all(color:AppColors.dorado,width:2.5)),
|
|
child:const Icon(Icons.delete_sweep_rounded,size:44,color:AppColors.dorado)),
|
|
const SizedBox(height:14),
|
|
const Text('H. AYUNTAMIENTO DE CELAYA',
|
|
style:TextStyle(color:Colors.white,fontSize:13,fontWeight:FontWeight.bold,letterSpacing:1.2)),
|
|
const SizedBox(height:4),
|
|
const Text('Sistema de Recolección de Residuos',
|
|
style:TextStyle(color:AppColors.dorado,fontSize:13)),
|
|
])),
|
|
Container(height:4,color:AppColors.dorado),
|
|
Padding(padding:const EdgeInsets.all(24), child:Card(elevation:4,
|
|
shape:RoundedRectangleBorder(borderRadius:BorderRadius.circular(12)),
|
|
child:Padding(padding:const EdgeInsets.all(24), child:Column(
|
|
crossAxisAlignment:CrossAxisAlignment.start, children:[
|
|
const Text('Iniciar Sesión',style:TextStyle(fontSize:20,
|
|
fontWeight:FontWeight.bold,color:AppColors.guindaPrimary)),
|
|
const SizedBox(height:16),
|
|
// Accesos rápidos demo
|
|
Container(padding:const EdgeInsets.all(10),
|
|
decoration:BoxDecoration(color:Colors.blue.shade50,borderRadius:BorderRadius.circular(8)),
|
|
child:const Column(crossAxisAlignment:CrossAxisAlignment.start, children:[
|
|
Text('Demo rápido:',style:TextStyle(fontWeight:FontWeight.bold,fontSize:12,color:AppColors.azulInfo)),
|
|
Text('Admin: admin@celaya.gob.mx / admin123',style:TextStyle(fontSize:11)),
|
|
Text('Conductor: conductor@celaya.gob.mx / conductor123',style:TextStyle(fontSize:11)),
|
|
])),
|
|
const SizedBox(height:16),
|
|
TextField(controller:_emailCtrl,keyboardType:TextInputType.emailAddress,
|
|
decoration:const InputDecoration(labelText:'Correo electrónico',
|
|
prefixIcon:Icon(Icons.email_outlined,color:AppColors.guindaPrimary),
|
|
border:OutlineInputBorder())),
|
|
const SizedBox(height:12),
|
|
TextField(controller:_passCtrl,obscureText:_obscure,
|
|
decoration:InputDecoration(labelText:'Contraseña',
|
|
prefixIcon:const Icon(Icons.lock_outline,color:AppColors.guindaPrimary),
|
|
border:const OutlineInputBorder(),
|
|
suffixIcon:IconButton(icon:Icon(_obscure?Icons.visibility_off:Icons.visibility),
|
|
onPressed:()=>setState(()=>_obscure=!_obscure)))),
|
|
const SizedBox(height:20),
|
|
SizedBox(width:double.infinity,height:50,
|
|
child:ElevatedButton(onPressed:_loading?null:_login,
|
|
style:ElevatedButton.styleFrom(backgroundColor:AppColors.guindaPrimary,
|
|
foregroundColor:Colors.white,shape:RoundedRectangleBorder(borderRadius:BorderRadius.circular(8))),
|
|
child:_loading?const CircularProgressIndicator(color:Colors.white,strokeWidth:2)
|
|
:const Text('ENTRAR',style:TextStyle(fontWeight:FontWeight.bold,letterSpacing:1)))),
|
|
const SizedBox(height:12),
|
|
const Divider(),
|
|
const SizedBox(height:12),
|
|
SizedBox(width:double.infinity,height:50,
|
|
child:OutlinedButton(onPressed:()=>Navigator.pushNamed(context,'/register'),
|
|
style:OutlinedButton.styleFrom(foregroundColor:AppColors.guindaPrimary,
|
|
side:const BorderSide(color:AppColors.guindaPrimary),
|
|
shape:RoundedRectangleBorder(borderRadius:BorderRadius.circular(8))),
|
|
child:const Text('CREAR CUENTA CIUDADANO',style:TextStyle(fontWeight:FontWeight.bold)))),
|
|
])))),
|
|
const Padding(padding:EdgeInsets.only(bottom:20),
|
|
child:Text('Gobierno Municipal de Celaya • Guanajuato',
|
|
style:TextStyle(color:AppColors.grisTexto,fontSize:11))),
|
|
])),
|
|
);
|
|
@override void dispose() { _emailCtrl.dispose(); _passCtrl.dispose(); super.dispose(); }
|
|
}
|