Initial commit
This commit is contained in:
149
lib/screens/crear_servicio_screen.dart
Normal file
149
lib/screens/crear_servicio_screen.dart
Normal file
@@ -0,0 +1,149 @@
|
||||
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'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user