190 lines
7.6 KiB
Dart
190 lines
7.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import '../../core/app_colors.dart';
|
|
import '../../data/celaya_colonias.dart';
|
|
import '../../data/colonies_data.dart';
|
|
import '../../database/db_helper.dart';
|
|
import '../../models/models.dart';
|
|
import '../../models/route_model.dart';
|
|
import '../../services/auth_service.dart';
|
|
|
|
class AddDomicilioScreen extends StatefulWidget {
|
|
final DomicilioModel? editing;
|
|
const AddDomicilioScreen({super.key, this.editing});
|
|
@override State<AddDomicilioScreen> createState() => _AddDomicilioScreenState();
|
|
}
|
|
|
|
class _AddDomicilioScreenState extends State<AddDomicilioScreen> {
|
|
final _calleCtrl = TextEditingController();
|
|
final _aliasCtrl = TextEditingController(text: 'Casa');
|
|
String? _coloniaSeleccionada;
|
|
ColonyModel? _coloniaData;
|
|
bool _loading = false;
|
|
String _searchQuery = '';
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
if (widget.editing != null) {
|
|
_calleCtrl.text = widget.editing!.calle;
|
|
_aliasCtrl.text = widget.editing!.alias;
|
|
_coloniaSeleccionada = widget.editing!.colonia;
|
|
_coloniaData = getColonyByName(widget.editing!.colonia);
|
|
}
|
|
}
|
|
|
|
List<String> get _filteredColonias {
|
|
if (_searchQuery.isEmpty) return celayaColonias;
|
|
return celayaColonias
|
|
.where((c) => c.toLowerCase().contains(_searchQuery.toLowerCase()))
|
|
.toList();
|
|
}
|
|
|
|
Future<void> _guardar() async {
|
|
if (_calleCtrl.text.trim().isEmpty || _coloniaSeleccionada == null) {
|
|
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
|
|
content: Text('Por favor completa todos los campos'),
|
|
backgroundColor: AppColors.rojoError));
|
|
return;
|
|
}
|
|
setState(() => _loading = true);
|
|
|
|
final auth = context.read<AuthService>();
|
|
final routeData = getColonyByName(_coloniaSeleccionada!);
|
|
final routeId = routeData?.routeId ?? 'RUTA-01';
|
|
final horario = routeData?.horarioEstimado ?? 'Matutino (06:00-08:00)';
|
|
|
|
if (widget.editing != null) {
|
|
// Editar existente — eliminar y volver a insertar
|
|
await DbHelper.deleteDomicilio(widget.editing!.id!);
|
|
}
|
|
|
|
final dom = DomicilioModel(
|
|
userId: auth.currentUser!.id!,
|
|
alias: _aliasCtrl.text.trim(),
|
|
calle: _calleCtrl.text.trim(),
|
|
colonia: _coloniaSeleccionada!,
|
|
routeId: routeId,
|
|
horarioEstimado: horario,
|
|
);
|
|
await DbHelper.insertDomicilio(dom);
|
|
await auth.reloadDomicilios();
|
|
|
|
if (!mounted) return;
|
|
setState(() => _loading = false);
|
|
Navigator.pop(context, true);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: AppColors.grisFondo,
|
|
appBar: AppBar(
|
|
backgroundColor: AppColors.guindaPrimary, foregroundColor: Colors.white,
|
|
title: Text(widget.editing != null ? 'Editar Domicilio' : 'Agregar Domicilio'),
|
|
bottom: PreferredSize(preferredSize: const Size.fromHeight(4),
|
|
child: Container(height: 4, color: AppColors.dorado)),
|
|
),
|
|
body: SingleChildScrollView(
|
|
padding: const EdgeInsets.all(16),
|
|
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
|
// Alias
|
|
TextField(
|
|
controller: _aliasCtrl,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Alias (ej. Casa, Trabajo, Familia)',
|
|
prefixIcon: Icon(Icons.label_outline, color: AppColors.guindaPrimary),
|
|
border: OutlineInputBorder(), filled: true, fillColor: Colors.white),
|
|
),
|
|
const SizedBox(height: 12),
|
|
// Calle
|
|
TextField(
|
|
controller: _calleCtrl,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Calle y número',
|
|
prefixIcon: Icon(Icons.signpost_outlined, color: AppColors.guindaPrimary),
|
|
border: OutlineInputBorder(), filled: true, fillColor: Colors.white),
|
|
),
|
|
const SizedBox(height: 16),
|
|
const Text('Colonia', style: TextStyle(fontWeight: FontWeight.bold,
|
|
color: AppColors.guindaPrimary, fontSize: 15)),
|
|
const SizedBox(height: 8),
|
|
// Buscador de colonias
|
|
TextField(
|
|
onChanged: (v) => setState(() => _searchQuery = v),
|
|
decoration: const InputDecoration(
|
|
hintText: 'Buscar colonia...',
|
|
prefixIcon: Icon(Icons.search),
|
|
border: OutlineInputBorder(), filled: true, fillColor: Colors.white,
|
|
isDense: true,
|
|
),
|
|
),
|
|
const SizedBox(height: 8),
|
|
// Lista de colonias
|
|
Container(
|
|
height: 240,
|
|
decoration: BoxDecoration(
|
|
color: Colors.white, borderRadius: BorderRadius.circular(8),
|
|
border: Border.all(color: Colors.grey.shade300)),
|
|
child: ListView.builder(
|
|
itemCount: _filteredColonias.length,
|
|
itemBuilder: (_, i) {
|
|
final c = _filteredColonias[i];
|
|
final isSelected = c == _coloniaSeleccionada;
|
|
return ListTile(
|
|
dense: true,
|
|
title: Text(c, style: TextStyle(fontSize: 13,
|
|
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
|
|
color: isSelected ? AppColors.guindaPrimary : AppColors.negroTexto)),
|
|
trailing: isSelected
|
|
? const Icon(Icons.check_circle, color: AppColors.guindaPrimary, size: 18)
|
|
: null,
|
|
tileColor: isSelected ? AppColors.guindaPrimary.withOpacity(0.08) : null,
|
|
onTap: () {
|
|
setState(() {
|
|
_coloniaSeleccionada = c;
|
|
_coloniaData = getColonyByName(c);
|
|
});
|
|
},
|
|
);
|
|
},
|
|
),
|
|
),
|
|
if (_coloniaData != null) ...[
|
|
const SizedBox(height: 12),
|
|
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 asignada: ${_coloniaData!.routeId}',
|
|
style: const TextStyle(fontWeight: FontWeight.bold,
|
|
color: AppColors.guindaPrimary, fontSize: 13)),
|
|
Text('Horario: ${_coloniaData!.horarioEstimado}',
|
|
style: const TextStyle(color: AppColors.grisTexto, fontSize: 12)),
|
|
]),
|
|
),
|
|
],
|
|
const SizedBox(height: 24),
|
|
SizedBox(width: double.infinity, height: 50,
|
|
child: ElevatedButton.icon(
|
|
onPressed: _loading ? null : _guardar,
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: AppColors.guindaPrimary, foregroundColor: Colors.white,
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8))),
|
|
icon: _loading
|
|
? const SizedBox(width: 18, height: 18,
|
|
child: CircularProgressIndicator(color: Colors.white, strokeWidth: 2))
|
|
: const Icon(Icons.save),
|
|
label: Text(widget.editing != null ? 'ACTUALIZAR' : 'GUARDAR DOMICILIO',
|
|
style: const TextStyle(fontWeight: FontWeight.bold)))),
|
|
]),
|
|
),
|
|
);
|
|
}
|
|
|
|
@override void dispose() { _calleCtrl.dispose(); _aliasCtrl.dispose(); super.dispose(); }
|
|
}
|