Created
September 9, 2025 16:08
-
-
Save gu1llermo/810c899b991a835c6f92406ad4188dac to your computer and use it in GitHub Desktop.
Provider para manejar el estado del formulario (Riverpod con anotaciones más Debounce)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import 'package:flutter/material.dart'; | |
| import 'package:homerun_club/core/mixins/debounce_mixin.dart'; | |
| import 'package:riverpod_annotation/riverpod_annotation.dart'; | |
| import '../../../../../core/constants/categories.dart'; | |
| import '../../../../shared/inputs/input_form.dart'; | |
| import '../../../../shared/inputs/inputs.dart'; | |
| import '../../../domain/entities/entities.dart'; | |
| import 'admin_agregar_atletas_provider.dart'; | |
| part 'admin_nuevo_atleta_provider.g.dart'; | |
| class AdminNuevoAtletaState { | |
| final bool isLoading; | |
| final bool hasError; | |
| final String statusMessage; | |
| // Entradas | |
| final SimpleString nombreAtleta; | |
| final SimpleString representante; | |
| final PhoneInput celular; | |
| final FechaInput fechaNacimiento; | |
| final FechaInput fechaInscripcion; | |
| final EquipoInput equipo; | |
| final SimpleStringWOValidation delegado; | |
| final SimpleStringWOValidation tecnico; | |
| final SimpleStringWOValidation manager; | |
| bool get isValidForm => InputForm.isValidInputs([ | |
| nombreAtleta, | |
| representante, | |
| celular, | |
| fechaNacimiento, | |
| fechaInscripcion, | |
| equipo, | |
| ]); | |
| AdminNuevoAtletaState({ | |
| this.isLoading = false, | |
| this.hasError = false, | |
| this.statusMessage = '', | |
| required this.nombreAtleta, | |
| required this.representante, | |
| required this.celular, | |
| required this.fechaNacimiento, | |
| required this.fechaInscripcion, | |
| required this.equipo, | |
| required this.delegado, | |
| required this.tecnico, | |
| required this.manager, | |
| }); | |
| AdminNuevoAtletaState copyWith({ | |
| bool? isLoading, | |
| bool? hasError, | |
| String? statusMessage, | |
| SimpleString? nombreAtleta, | |
| SimpleString? representante, | |
| PhoneInput? celular, | |
| FechaInput? fechaNacimiento, | |
| FechaInput? fechaInscripcion, | |
| EquipoInput? equipo, | |
| SimpleStringWOValidation? delegado, | |
| SimpleStringWOValidation? tecnico, | |
| SimpleStringWOValidation? manager, | |
| }) => AdminNuevoAtletaState( | |
| isLoading: isLoading ?? this.isLoading, | |
| hasError: hasError ?? this.hasError, | |
| statusMessage: statusMessage ?? this.statusMessage, | |
| nombreAtleta: nombreAtleta ?? this.nombreAtleta, | |
| representante: representante ?? this.representante, | |
| celular: celular ?? this.celular, | |
| fechaNacimiento: fechaNacimiento ?? this.fechaNacimiento, | |
| fechaInscripcion: fechaInscripcion ?? this.fechaInscripcion, | |
| equipo: equipo ?? this.equipo, | |
| delegado: delegado ?? this.delegado, | |
| tecnico: tecnico ?? this.tecnico, | |
| manager: manager ?? this.manager, | |
| ); | |
| } | |
| @Riverpod(keepAlive: true, dependencies: [AdminAgregarAtletasNotifier]) | |
| class AdminNuevoAtletaNotifier extends _$AdminNuevoAtletaNotifier | |
| with DebounceMixin { | |
| TextEditingController? _nombreAtletaController; | |
| TextEditingController? _representanteController; | |
| TextEditingController? _celularController; | |
| TextEditingController? _delegadoController; | |
| TextEditingController? _tecnicoController; | |
| TextEditingController? _managerController; | |
| @override | |
| AdminNuevoAtletaState build() { | |
| _nombreAtletaController = TextEditingController(); | |
| _nombreAtletaController!.addListener(_nombreAtletaListener); | |
| _representanteController = TextEditingController(); | |
| _representanteController!.addListener(_representanteListener); | |
| _celularController = TextEditingController(); | |
| _celularController!.addListener(_celularListener); | |
| _delegadoController = TextEditingController(); | |
| _tecnicoController = TextEditingController(); | |
| _managerController = TextEditingController(); | |
| ref.onDispose(() { | |
| _nombreAtletaController?.removeListener(_nombreAtletaListener); | |
| _nombreAtletaController?.dispose(); | |
| _representanteController?.removeListener(_representanteListener); | |
| _representanteController?.dispose(); | |
| _celularController?.removeListener(_celularListener); | |
| _celularController?.dispose(); | |
| _delegadoController?.dispose(); | |
| _tecnicoController?.dispose(); | |
| _managerController?.dispose(); | |
| cancelAllDebouncers(); | |
| }); | |
| return AdminNuevoAtletaState( | |
| nombreAtleta: SimpleString( | |
| value: '', | |
| controller: _nombreAtletaController, | |
| ), | |
| representante: SimpleString( | |
| value: '', | |
| controller: _representanteController, | |
| ), | |
| celular: PhoneInput(value: '', controller: _celularController), | |
| fechaNacimiento: const FechaInput(value: null), | |
| fechaInscripcion: const FechaInput(value: null), | |
| equipo: const EquipoInput(value: null), | |
| delegado: SimpleStringWOValidation( | |
| value: '', | |
| controller: _delegadoController, | |
| ), | |
| tecnico: SimpleStringWOValidation( | |
| value: '', | |
| controller: _tecnicoController, | |
| ), | |
| manager: SimpleStringWOValidation( | |
| value: '', | |
| controller: _managerController, | |
| ), | |
| ); | |
| } | |
| void refreshState() { | |
| state = state.copyWith(); | |
| } | |
| void onNombreAtletaChanged() { | |
| final nombreAtleta = state.nombreAtleta; | |
| final value = nombreAtleta.controller?.text ?? ''; | |
| final nombreAtletaChanged = nombreAtleta.onChanged(value); | |
| state = state.copyWith(nombreAtleta: nombreAtletaChanged); | |
| } | |
| void _nombreAtletaListener() { | |
| debounce('nombreAtleta', onNombreAtletaChanged); | |
| } | |
| void onNombreAtletaValidate() { | |
| final nombreAtleta = state.nombreAtleta; | |
| final nombreAtletaValidated = nombreAtleta.validate(); | |
| state = state.copyWith(nombreAtleta: nombreAtletaValidated); | |
| } | |
| void onRepresentanteChanged() { | |
| final representante = state.representante; | |
| final value = representante.controller?.text ?? ''; | |
| final representanteChanged = representante.onChanged(value); | |
| state = state.copyWith(representante: representanteChanged); | |
| } | |
| void _representanteListener() { | |
| debounce('representante', onRepresentanteChanged); | |
| } | |
| void onRepresentanteValidate() { | |
| final representante = state.representante; | |
| final representanteValidated = representante.validate(); | |
| state = state.copyWith(representante: representanteValidated); | |
| } | |
| void onCelularChanged() { | |
| final celular = state.celular; | |
| final value = celular.controller?.text ?? ''; | |
| final celularChanged = celular.onChanged(value); | |
| state = state.copyWith(celular: celularChanged); | |
| } | |
| void _celularListener() { | |
| debounce('celular', onCelularChanged); | |
| } | |
| void onCelularValidate() { | |
| final celular = state.celular; | |
| final celularValidated = celular.validate(); | |
| state = state.copyWith(celular: celularValidated); | |
| } | |
| void onFechaNacimientoChanged(DateTime? value) { | |
| final fechaNacimiento = state.fechaNacimiento; | |
| final fechaNacimientoChanged = fechaNacimiento.onChanged(value); | |
| state = state.copyWith(fechaNacimiento: fechaNacimientoChanged); | |
| } | |
| void onFechaNacimientoValidate() { | |
| final fechaNacimiento = state.fechaNacimiento; | |
| final fechaNacimientoValidated = fechaNacimiento.validate(); | |
| state = state.copyWith(fechaNacimiento: fechaNacimientoValidated); | |
| } | |
| void onFechaInscripcionChanged(DateTime? value) { | |
| final fechaInscripcion = state.fechaInscripcion; | |
| final fechaInscripcionChanged = fechaInscripcion.onChanged(value); | |
| state = state.copyWith(fechaInscripcion: fechaInscripcionChanged); | |
| } | |
| void onFechaInscripcionValidate() { | |
| final fechaInscripcion = state.fechaInscripcion; | |
| final fechaInscripcionValidated = fechaInscripcion.validate(); | |
| state = state.copyWith(fechaInscripcion: fechaInscripcionValidated); | |
| } | |
| void onEquipoChanged(Equipo? value) { | |
| final equipo = state.equipo; | |
| final equipoChanged = equipo.onChanged(value); | |
| state = state.copyWith(equipo: equipoChanged); | |
| } | |
| void onEquipoValidate() { | |
| final equipo = state.equipo; | |
| final equipoValidated = equipo.validate(); | |
| state = state.copyWith(equipo: equipoValidated); | |
| } | |
| void validateInputs() { | |
| onNombreAtletaValidate(); | |
| onRepresentanteValidate(); | |
| onCelularValidate(); | |
| onFechaNacimientoValidate(); | |
| onFechaInscripcionValidate(); | |
| onEquipoValidate(); | |
| } | |
| Future<bool> onFormSubmit() async { | |
| if (state.isLoading) return false; | |
| state = state.copyWith(isLoading: true); | |
| validateInputs(); | |
| if (!state.isValidForm) { | |
| state = state.copyWith(isLoading: false); | |
| return false; | |
| } | |
| // si llega aquí es porque todo está bien | |
| try { | |
| final atleta = AtletaEntity( | |
| nombreAtleta: state.nombreAtleta.value, | |
| fechaNacimiento: state.fechaNacimiento.value!, | |
| equipo: state.equipo.value!, | |
| nombreRepresentante: state.representante.value, | |
| celular: int.parse( | |
| '${state.celular.countryCode}${state.celular.value}', | |
| ), | |
| fechaInicio: state.fechaInscripcion.value!, | |
| manager: state.manager.controller?.text ?? '', | |
| tecnico: state.tecnico.controller?.text ?? '', | |
| delegado: state.delegado.controller?.text ?? '', | |
| pagos: [], | |
| ); | |
| await ref | |
| .read(adminAgregarAtletasNotifierProvider.notifier) | |
| .addAtleta(atleta); | |
| ref.invalidateSelf(); | |
| return true; | |
| } catch (e, stackTrace) { | |
| print('$e, $stackTrace'); | |
| await setError(e.toString()); | |
| return false; | |
| } finally { | |
| state = state.copyWith(isLoading: false); | |
| } | |
| } | |
| Future<void> setError(String error) async { | |
| state = state.copyWith( | |
| statusMessage: error, | |
| isLoading: false, | |
| hasError: true, | |
| ); | |
| await Future.delayed(const Duration(seconds: 3)); | |
| state = state.copyWith(statusMessage: '', hasError: false); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment