Actualizacion del programa
This commit is contained in:
105
celaya_limpia/lib/screens/register_screen.dart
Normal file
105
celaya_limpia/lib/screens/register_screen.dart
Normal file
@@ -0,0 +1,105 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../core/app_colors.dart';
|
||||
import '../data/colonies_data.dart';
|
||||
import '../data/celaya_colonias.dart';
|
||||
import '../models/route_model.dart';
|
||||
import '../services/auth_service.dart';
|
||||
|
||||
class RegisterScreen extends StatefulWidget {
|
||||
const RegisterScreen({super.key});
|
||||
@override State<RegisterScreen> createState() => _RegisterScreenState();
|
||||
}
|
||||
|
||||
class _RegisterScreenState extends State<RegisterScreen> {
|
||||
final _nombre = TextEditingController();
|
||||
final _email = TextEditingController();
|
||||
final _pass = TextEditingController();
|
||||
final _calle = TextEditingController();
|
||||
ColonyModel? _colony;
|
||||
bool _loading = false, _obscure = true;
|
||||
|
||||
Future<void> _register() async {
|
||||
if ([_nombre,_email,_pass,_calle].any((c)=>c.text.trim().isEmpty) || _colony==null) {
|
||||
_snack('Completa todos los campos', isError:true); return; }
|
||||
if (_pass.text.length < 6) { _snack('Contraseña mínimo 6 caracteres', isError:true); return; }
|
||||
setState(()=>_loading=true);
|
||||
final err = await context.read<AuthService>().register(
|
||||
nombre:_nombre.text, email:_email.text, password:_pass.text,
|
||||
calle:_calle.text, colonia:_colony!.colonia,
|
||||
routeId:_colony!.routeId, horarioEstimado:_colony!.horarioEstimado);
|
||||
if (!mounted) return;
|
||||
setState(()=>_loading=false);
|
||||
if (err!=null) { _snack(err,isError:true); return; }
|
||||
Navigator.pushReplacementNamed(context, '/home');
|
||||
}
|
||||
|
||||
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,
|
||||
appBar: AppBar(backgroundColor:AppColors.guindaPrimary,foregroundColor:Colors.white,
|
||||
title:const Text('Registro Ciudadano'),
|
||||
bottom:PreferredSize(preferredSize:const Size.fromHeight(4),
|
||||
child:Container(height:4,color:AppColors.dorado))),
|
||||
body: SingleChildScrollView(padding:const EdgeInsets.all(20), child:Column(children:[
|
||||
_field(_nombre,'Nombre completo',Icons.badge_outlined),
|
||||
const SizedBox(height:12),
|
||||
_field(_email,'Correo electrónico',Icons.email_outlined,type:TextInputType.emailAddress),
|
||||
const SizedBox(height:12),
|
||||
TextField(controller:_pass,obscureText:_obscure,
|
||||
decoration:InputDecoration(labelText:'Contraseña (mín. 6)',
|
||||
prefixIcon:const Icon(Icons.lock_outline,color:AppColors.guindaPrimary),
|
||||
border:const OutlineInputBorder(),filled:true,fillColor:Colors.white,
|
||||
suffixIcon:IconButton(icon:Icon(_obscure?Icons.visibility_off:Icons.visibility),
|
||||
onPressed:()=>setState(()=>_obscure=!_obscure)))),
|
||||
const SizedBox(height:20),
|
||||
const Align(alignment:Alignment.centerLeft,
|
||||
child:Text('Domicilio',style:TextStyle(fontWeight:FontWeight.bold,color:AppColors.guindaPrimary,fontSize:16))),
|
||||
const SizedBox(height:10),
|
||||
_field(_calle,'Calle y número',Icons.signpost_outlined),
|
||||
const SizedBox(height:12),
|
||||
DropdownButtonFormField<String>(
|
||||
decoration:const InputDecoration(labelText:'Colonia',
|
||||
prefixIcon:Icon(Icons.location_city,color:AppColors.guindaPrimary),
|
||||
border:OutlineInputBorder(),filled:true,fillColor:Colors.white),
|
||||
hint:const Text('Selecciona tu colonia'),
|
||||
value:_colony?.colonia, isExpanded:true,
|
||||
items:celayaColonias.map((n)=>DropdownMenuItem(value:n,child:Text(n,style:const TextStyle(fontSize:13)))).toList(),
|
||||
onChanged:(v){ if(v!=null) setState((){
|
||||
_colony = getColonyByName(v) ?? ColonyModel(
|
||||
colonia:v, routeId:'RUTA-01', horarioEstimado:'Matutino (06:00-08:00)');
|
||||
}); }),
|
||||
if (_colony!=null) ...[
|
||||
const SizedBox(height:10),
|
||||
Container(padding:const EdgeInsets.all(12),
|
||||
decoration:BoxDecoration(color:AppColors.guindaPrimary.withOpacity(0.08),
|
||||
borderRadius:BorderRadius.circular(8),
|
||||
border:Border.all(color:AppColors.guindaPrimary.withOpacity(0.3))),
|
||||
child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[
|
||||
Text('Ruta: ${_colony!.routeId}',style:const TextStyle(color:AppColors.guindaPrimary,fontWeight:FontWeight.bold)),
|
||||
Text('Horario: ${_colony!.horarioEstimado}',style:const TextStyle(color:AppColors.grisTexto,fontSize:12)),
|
||||
]))],
|
||||
const SizedBox(height:24),
|
||||
SizedBox(width:double.infinity,height:50,
|
||||
child:ElevatedButton(onPressed:_loading?null:_register,
|
||||
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('REGISTRARME',style:TextStyle(fontWeight:FontWeight.bold,letterSpacing:1)))),
|
||||
const SizedBox(height:20),
|
||||
])),
|
||||
);
|
||||
|
||||
Widget _field(TextEditingController c, String label, IconData icon,
|
||||
{TextInputType type=TextInputType.text}) =>
|
||||
TextField(controller:c,keyboardType:type,
|
||||
decoration:InputDecoration(labelText:label,
|
||||
prefixIcon:Icon(icon,color:AppColors.guindaPrimary),
|
||||
border:const OutlineInputBorder(),filled:true,fillColor:Colors.white));
|
||||
|
||||
@override void dispose(){ _nombre.dispose();_email.dispose();_pass.dispose();_calle.dispose();super.dispose(); }
|
||||
}
|
||||
Reference in New Issue
Block a user