150 lines
5.9 KiB
Dart
150 lines
5.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:intl/intl.dart';
|
|
import '../models/servicio.dart';
|
|
import '../providers/servicio_provider.dart';
|
|
|
|
class CrearServicioScreen extends StatefulWidget {
|
|
final Servicio? servicio;
|
|
const CrearServicioScreen({super.key, this.servicio});
|
|
|
|
@override
|
|
State<CrearServicioScreen> createState() => _CrearServicioScreenState();
|
|
}
|
|
|
|
class _CrearServicioScreenState extends State<CrearServicioScreen> {
|
|
final _formKey = GlobalKey<FormState>();
|
|
late TextEditingController _nombreCtrl;
|
|
String _iconoSeleccionado = 'recibo';
|
|
Color _colorSeleccionado = Colors.purple;
|
|
int _diaVencimiento = 15;
|
|
|
|
final List<Map<String, dynamic>> _iconos = [
|
|
{'key': 'electricidad', 'icon': Icons.bolt, 'label': 'Electricidad'},
|
|
{'key': 'agua', 'icon': Icons.water_drop, 'label': 'Agua'},
|
|
{'key': 'internet', 'icon': Icons.wifi, 'label': 'Internet'},
|
|
{'key': 'cable', 'icon': Icons.tv, 'label': 'Cable'},
|
|
{'key': 'telefono', 'icon': Icons.phone, 'label': 'Teléfono'},
|
|
{'key': 'gas', 'icon': Icons.local_fire_department, 'label': 'Gas'},
|
|
{'key': 'alquiler', 'icon': Icons.home, 'label': 'Alquiler'},
|
|
{'key': 'recibo', 'icon': Icons.receipt, 'label': 'Otros'},
|
|
];
|
|
|
|
final List<Color> _colores = [
|
|
Colors.red, Colors.pink, Colors.purple, Colors.deepPurple,
|
|
Colors.indigo, Colors.blue, Colors.lightBlue, Colors.cyan,
|
|
Colors.teal, Colors.green, Colors.lightGreen, Colors.lime,
|
|
Colors.yellow, Colors.amber, Colors.orange, Colors.deepOrange,
|
|
Colors.brown, Colors.grey, Colors.blueGrey,
|
|
];
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_nombreCtrl = TextEditingController(text: widget.servicio?.nombre ?? '');
|
|
if (widget.servicio != null) {
|
|
_iconoSeleccionado = widget.servicio!.icono;
|
|
_colorSeleccionado = Color(widget.servicio!.color);
|
|
_diaVencimiento = widget.servicio!.diaVencimiento;
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_nombreCtrl.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final provider = context.read<ServicioProvider>();
|
|
|
|
return Scaffold(
|
|
appBar: AppBar(title: Text(widget.servicio != null ? 'Editar servicio' : 'Nuevo servicio')),
|
|
body: Form(
|
|
key: _formKey,
|
|
child: ListView(
|
|
padding: const EdgeInsets.all(16),
|
|
children: [
|
|
TextFormField(
|
|
controller: _nombreCtrl,
|
|
decoration: const InputDecoration(labelText: 'Nombre del servicio', border: OutlineInputBorder()),
|
|
validator: (v) => v == null || v.trim().isEmpty ? 'Ingresa el nombre' : null,
|
|
),
|
|
const SizedBox(height: 20),
|
|
Text('Icono', style: Theme.of(context).textTheme.titleSmall),
|
|
const SizedBox(height: 8),
|
|
Wrap(
|
|
spacing: 8,
|
|
runSpacing: 8,
|
|
children: _iconos.map((item) {
|
|
final selected = _iconoSeleccionado == item['key'];
|
|
return ChoiceChip(
|
|
selected: selected,
|
|
avatar: Icon(item['icon'] as IconData, size: 20),
|
|
label: Text(item['label'] as String, style: const TextStyle(fontSize: 12)),
|
|
onSelected: (_) => setState(() => _iconoSeleccionado = item['key'] as String),
|
|
);
|
|
}).toList(),
|
|
),
|
|
const SizedBox(height: 20),
|
|
Text('Color', style: Theme.of(context).textTheme.titleSmall),
|
|
const SizedBox(height: 8),
|
|
Wrap(
|
|
spacing: 6,
|
|
runSpacing: 6,
|
|
children: _colores.map((c) {
|
|
final selected = _colorSeleccionado == c;
|
|
return GestureDetector(
|
|
onTap: () => setState(() => _colorSeleccionado = c),
|
|
child: Container(
|
|
width: 36,
|
|
height: 36,
|
|
decoration: BoxDecoration(
|
|
color: c,
|
|
shape: BoxShape.circle,
|
|
border: selected ? Border.all(color: Colors.white, width: 3) : null,
|
|
boxShadow: selected ? [BoxShadow(color: c.withValues(alpha: 0.5), blurRadius: 8)] : null,
|
|
),
|
|
child: selected ? const Icon(Icons.check, color: Colors.white, size: 18) : null,
|
|
),
|
|
);
|
|
}).toList(),
|
|
),
|
|
const SizedBox(height: 20),
|
|
Text('Día de vencimiento', style: Theme.of(context).textTheme.titleSmall),
|
|
const SizedBox(height: 8),
|
|
DropdownButtonFormField<int>(
|
|
value: _diaVencimiento,
|
|
decoration: const InputDecoration(border: OutlineInputBorder()),
|
|
items: List.generate(28, (i) => DropdownMenuItem(value: i + 1, child: Text('${i + 1}'))),
|
|
onChanged: (v) => setState(() => _diaVencimiento = v!),
|
|
),
|
|
const SizedBox(height: 32),
|
|
FilledButton(
|
|
onPressed: () async {
|
|
if (!_formKey.currentState!.validate()) return;
|
|
final servicio = Servicio(
|
|
id: widget.servicio?.id,
|
|
nombre: _nombreCtrl.text.trim(),
|
|
icono: _iconoSeleccionado,
|
|
color: _colorSeleccionado.value,
|
|
diaVencimiento: _diaVencimiento,
|
|
fechaCreacion: widget.servicio?.fechaCreacion ?? DateFormat('yyyy-MM-dd').format(DateTime.now()),
|
|
);
|
|
if (widget.servicio != null) {
|
|
await provider.actualizarServicio(servicio);
|
|
} else {
|
|
await provider.agregarServicio(servicio);
|
|
}
|
|
if (context.mounted) Navigator.pop(context);
|
|
},
|
|
child: Text(widget.servicio != null ? 'Guardar cambios' : 'Crear servicio'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|