From 5c599893164f5412960fd40a8d0a19f2423deacd Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 10 Sep 2024 14:43:30 -0300 Subject: [PATCH] Fix: Ajustes no Custom input, custom Select e Upload de media --- .../shared_components_atoms/custom_input.dart | 12 +- .../custom_select.dart | 35 +++ .../media_upload_button.dart | 35 ++- .../submit_button.dart | 5 +- lib/pages/pets_page/pets_page_model.dart | 87 +++++- lib/pages/pets_page/pets_page_widget.dart | 291 ++++++++++-------- pubspec.lock | 24 +- 7 files changed, 322 insertions(+), 167 deletions(-) diff --git a/lib/components/atomic_components/shared_components_atoms/custom_input.dart b/lib/components/atomic_components/shared_components_atoms/custom_input.dart index d4b48f95..8d207744 100644 --- a/lib/components/atomic_components/shared_components_atoms/custom_input.dart +++ b/lib/components/atomic_components/shared_components_atoms/custom_input.dart @@ -1,3 +1,4 @@ +import 'package:easy_debounce/easy_debounce.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:google_fonts/google_fonts.dart'; @@ -16,8 +17,9 @@ class CustomInputUtil extends StatefulWidget { final TextInputAction textInputAction; final TextInputType keyboardType; final int maxLength; - final FormFieldValidator? validator; + final String? Function(String?)? validator; final bool haveMaxLength; + final void Function(String)? onChanged; CustomInputUtil( {Key? key, @@ -27,6 +29,7 @@ class CustomInputUtil extends StatefulWidget { required this.suffixIcon, this.autoFocus = false, required this.focusNode, + this.onChanged, this.textInputAction = TextInputAction.next, this.keyboardType = TextInputType.text, this.maxLength = 80, @@ -54,8 +57,14 @@ class _CustomInputUtilState extends State { TextFormField( controller: widget.controller, autovalidateMode: AutovalidateMode.onUserInteraction, + validator: widget.validator, autofocus: widget.autoFocus, focusNode: widget.focusNode, + onChanged: (_) => EasyDebounce.debounce( + '${widget.controller}', + const Duration(milliseconds: 500), + () => setState(() {}), + ), textInputAction: widget.textInputAction, obscureText: false, decoration: InputDecoration( @@ -122,7 +131,6 @@ class _CustomInputUtilState extends State { inputFormatters: [ LengthLimitingTextInputFormatter(widget.maxLength) ], - validator: widget.validator, ), ], ), diff --git a/lib/components/atomic_components/shared_components_atoms/custom_select.dart b/lib/components/atomic_components/shared_components_atoms/custom_select.dart index 0002ddd8..a15f262c 100644 --- a/lib/components/atomic_components/shared_components_atoms/custom_select.dart +++ b/lib/components/atomic_components/shared_components_atoms/custom_select.dart @@ -18,6 +18,7 @@ class CustomSelect extends StatefulWidget { FormFieldController controller; dynamic Function(String?)? changed; String? dropDownValue; + bool isRequired; CustomSelect({ Key? key, @@ -26,6 +27,7 @@ class CustomSelect extends StatefulWidget { required this.hintText, required this.controller, required this.changed, + this.isRequired = false, this.dropDownValue, this.isMultiSelect = false, }) : super(key: key); @@ -99,6 +101,39 @@ class _CustomSelectState extends State { ), ], ), + if (widget.isRequired) + if (widget.dropDownValue == null || widget.dropDownValue == '') + Padding( + padding: + const EdgeInsetsDirectional.fromSTEB(24.0, 0.0, 24.0, 0.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: + const EdgeInsetsDirectional.only(top: 5, start: 15), + child: Text( + FFLocalizations.of(context).getVariableText( + enText: 'This field is required', + ptText: 'Este campo é obrigatório', + ), + style: FlutterFlowTheme.of(context) + .bodySmall + .override( + fontFamily: FlutterFlowTheme.of(context) + .bodySmallFamily, + color: + FlutterFlowTheme.of(context).customColor6, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context) + .bodySmallFamily), + )), + ), + ], + ), + ), ], ), ); diff --git a/lib/components/atomic_components/shared_components_atoms/media_upload_button.dart b/lib/components/atomic_components/shared_components_atoms/media_upload_button.dart index f496a5a3..ff0277c8 100644 --- a/lib/components/atomic_components/shared_components_atoms/media_upload_button.dart +++ b/lib/components/atomic_components/shared_components_atoms/media_upload_button.dart @@ -1,3 +1,4 @@ +import 'dart:developer'; import 'dart:typed_data'; import 'package:flutter/material.dart'; @@ -9,13 +10,13 @@ import 'package:hub/flutter_flow/upload_data.dart'; import 'package:hub/flutter_flow/uploaded_file.dart'; class MediaUploadButtonUtil extends StatefulWidget { - final FFUploadedFile uploadedFile; - final bool isUploading; + final Function(FFUploadedFile) onUploadComplete; + bool isUploading; final String labelText; - const MediaUploadButtonUtil( + MediaUploadButtonUtil( {Key? key, - required this.uploadedFile, + required this.onUploadComplete, required this.isUploading, required this.labelText}) : super(key: key); @@ -25,13 +26,12 @@ class MediaUploadButtonUtil extends StatefulWidget { } class _MediaUploadButtonUtilState extends State { - late FFUploadedFile _uploadedFile; - late bool _isUploading; + FFUploadedFile _uploadedFiles = FFUploadedFile(bytes: Uint8List.fromList([])); + @override void initState() { super.initState(); - _uploadedFile = widget.uploadedFile ?? FFUploadedFile(); - _isUploading = widget.isUploading ?? false; + _uploadedFiles = FFUploadedFile(bytes: Uint8List.fromList([])); } @override @@ -40,7 +40,7 @@ class _MediaUploadButtonUtilState extends State { padding: const EdgeInsetsDirectional.fromSTEB(24.0, 0.0, 24.0, 0.0), child: Builder( builder: (context) { - if ((_uploadedFile.bytes?.isNotEmpty ?? false)) { + if ((_uploadedFiles.bytes?.isNotEmpty ?? false)) { return InkWell( splashColor: Colors.transparent, focusColor: Colors.transparent, @@ -48,14 +48,16 @@ class _MediaUploadButtonUtilState extends State { highlightColor: Colors.transparent, onTap: () async { setState(() { - _isUploading = false; - _uploadedFile = FFUploadedFile(bytes: Uint8List.fromList([])); + widget.isUploading = false; + _uploadedFiles = + FFUploadedFile(bytes: Uint8List.fromList([])); + widget.onUploadComplete(_uploadedFiles); }); }, child: ClipRRect( borderRadius: BorderRadius.circular(8.0), child: Image.memory( - _uploadedFile.bytes ?? Uint8List.fromList([]), + _uploadedFiles.bytes ?? Uint8List.fromList([]), width: 300.0, height: 200.0, fit: BoxFit.cover, @@ -77,7 +79,7 @@ class _MediaUploadButtonUtilState extends State { includeDimensions: true, ); if (selectedMedia != null) { - setState(() => _isUploading = true); + setState(() => widget.isUploading = true); var selectedUploadedFiles = []; try { @@ -95,15 +97,18 @@ class _MediaUploadButtonUtilState extends State { // blurHash: m.blurHash, )) .toList(); + log(selectedUploadedFiles.toString()); } finally { ScaffoldMessenger.of(context).hideCurrentSnackBar(); - _isUploading = false; + widget.isUploading = false; } if (selectedUploadedFiles.length == selectedMedia.length) { setState(() { - _uploadedFile = selectedUploadedFiles.first; + _uploadedFiles = selectedUploadedFiles.first; }); + widget.onUploadComplete(_uploadedFiles); + showUploadMessage(context, 'Success!'); } else { setState(() {}); diff --git a/lib/components/atomic_components/shared_components_atoms/submit_button.dart b/lib/components/atomic_components/shared_components_atoms/submit_button.dart index 0f261e31..5be97e1b 100644 --- a/lib/components/atomic_components/shared_components_atoms/submit_button.dart +++ b/lib/components/atomic_components/shared_components_atoms/submit_button.dart @@ -3,12 +3,13 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/flutter_flow_widgets.dart'; import 'package:hub/flutter_flow/internationalization.dart'; +import 'package:json_path/fun_sdk.dart'; class SubmitButtonUtil extends StatelessWidget { final String labelText; - final VoidCallback onPressed; + Future Function()? onPressed; - const SubmitButtonUtil({ + SubmitButtonUtil({ required this.labelText, required this.onPressed, }); diff --git a/lib/pages/pets_page/pets_page_model.dart b/lib/pages/pets_page/pets_page_model.dart index 99938f3d..bdd7e0aa 100644 --- a/lib/pages/pets_page/pets_page_model.dart +++ b/lib/pages/pets_page/pets_page_model.dart @@ -1,17 +1,22 @@ import 'dart:developer'; import 'package:flutter/material.dart'; +import 'package:hub/backend/api_requests/api_manager.dart'; import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/flutter_flow/form_field_controller.dart'; import 'package:hub/pages/pets_page/pets_page_widget.dart'; import 'package:hub/shared/utils/log_util.dart'; +import '/custom_code/actions/index.dart' as actions; class PetsPageModel extends FlutterFlowModel { late final TabController tabBarController; + ApiCallResponse? petsResponse; + // Controller para o Upload de Arquivos bool isDataUploading = false; FFUploadedFile uploadedLocalFile = FFUploadedFile(bytes: Uint8List.fromList([])); + String? imgBase64; // Controller para o DropDown String? dropDownValue1; @@ -23,8 +28,7 @@ class PetsPageModel extends FlutterFlowModel { // Controller para o TextField FocusNode? textFieldFocusName; TextEditingController? textControllerName; - String? Function(BuildContext, String?)? textControllerNameValidator; - String? _textControllerNameValidator(BuildContext context, String? val) { + String? textControllerNameValidator(BuildContext context, String? val) { if (val == null || val.isEmpty) { return FFLocalizations.of(context).getVariableText( enText: 'This field is required', @@ -36,11 +40,27 @@ class PetsPageModel extends FlutterFlowModel { FocusNode? textFieldFocusSpecies; TextEditingController? textControllerSpecies; - String? Function(BuildContext, String?)? textControllerSpeciesValidator; + String? textControllerSpeciesValidator(BuildContext context, String? val) { + if (val == null || val.isEmpty) { + return FFLocalizations.of(context).getVariableText( + enText: 'This field is required', + ptText: 'Este campo é obrigatório', + ); + } + return null; + } FocusNode? textFieldFocusRace; TextEditingController? textControllerRace; - String? Function(BuildContext, String?)? textControllerRaceValidator; + String? textControllerRaceValidator(BuildContext context, String? val) { + if (val == null || val.isEmpty) { + return FFLocalizations.of(context).getVariableText( + enText: 'This field is required', + ptText: 'Este campo é obrigatório', + ); + } + return null; + } FocusNode? textFieldFocusColor; TextEditingController? textControllerColor; @@ -49,8 +69,7 @@ class PetsPageModel extends FlutterFlowModel { DateTime? selectedDate; FocusNode? textFieldFocusData; TextEditingController? textControllerData; - String? Function(BuildContext, String?)? textControllerDataValidator; - String? _textControllerDataValidator(BuildContext context, String? val) { + String? textControllerDataValidator(BuildContext context, String? val) { if (val == null || val.isEmpty) { return FFLocalizations.of(context).getVariableText( enText: 'This field is required.', @@ -74,8 +93,17 @@ class PetsPageModel extends FlutterFlowModel { textFieldFocusName = FocusNode(); textControllerName = TextEditingController(); - textControllerNameValidator = - (context, value) => _textControllerNameValidator(context, value); + // textControllerNameValidator = + // (context, value) => _textControllerNameValidator(context, value); + + textFieldFocusSpecies = FocusNode(); + textControllerSpecies = TextEditingController(); + + textFieldFocusRace = FocusNode(); + textControllerRace = TextEditingController(); + + textFieldFocusColor = FocusNode(); + textControllerColor = TextEditingController(); textFieldFocusData = FocusNode(); textControllerData = TextEditingController( @@ -83,7 +111,9 @@ class PetsPageModel extends FlutterFlowModel { 'dd/MM/yyyy', DateTime.now(), )); - textControllerDataValidator = _textControllerDataValidator; + + textFieldFocusObservation = FocusNode(); + textControllerObservation = TextEditingController(); dropDownValueController1 = FormFieldController(dropDownValue1 ??= 'Selecione uma opção'); @@ -117,4 +147,43 @@ class PetsPageModel extends FlutterFlowModel { dropDownValueController1?.dispose(); dropDownValueController2?.dispose(); } + + // Validador do formulário + bool isFormValid(BuildContext context) { + if (uploadedLocalFile.bytes?.isEmpty ?? true) { + return false; + } + if (textControllerName.text.isEmpty || + textControllerName.text.length > 80 || + textControllerName.text == '') { + return false; + } + if (textControllerSpecies.text.isEmpty || + textControllerSpecies.text == '') { + return false; + } + if (textControllerRace.text.isEmpty || textControllerRace.text == '') { + return false; + } + if (textControllerData.text.isEmpty || textControllerData.text == '') { + return false; + } + if (dropDownValue1 == null || + dropDownValue1!.isEmpty || + dropDownValue1 == '') { + return false; + } + if (dropDownValue2 == null) { + return false; + } + return true; + } + + Future registerPet() async { + if (isFormValid == true) { + imgBase64 = await actions.convertImageFileToBase64( + uploadedLocalFile, + ); + } + } } diff --git a/lib/pages/pets_page/pets_page_widget.dart b/lib/pages/pets_page/pets_page_widget.dart index 61f2767f..cee83bae 100644 --- a/lib/pages/pets_page/pets_page_widget.dart +++ b/lib/pages/pets_page/pets_page_widget.dart @@ -1,5 +1,6 @@ import 'dart:developer'; +import 'package:easy_debounce/easy_debounce.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -32,7 +33,8 @@ class PetsPageWidget extends StatefulWidget { State createState() => _PetsPageWidgetState(); } -class _PetsPageWidgetState extends State with SingleTickerProviderStateMixin { +class _PetsPageWidgetState extends State + with SingleTickerProviderStateMixin { late PetsPageModel _model; final _formKey = GlobalKey(); @@ -60,9 +62,11 @@ class _PetsPageWidgetState extends State with SingleTickerProvid _model.textControllerObservation ??= TextEditingController(); _model.textFieldFocusObservation ??= FocusNode(); - _model.dropDownValueController1 ??= FormFieldController(_model.dropDownValue1 ??= ''); + _model.dropDownValueController1 ??= + FormFieldController(_model.dropDownValue1 ??= ''); - _model.dropDownValueController2 ??= FormFieldController(_model.dropDownValue2 ??= ''); + _model.dropDownValueController2 ??= + FormFieldController(_model.dropDownValue2 ??= ''); } @override @@ -71,6 +75,12 @@ class _PetsPageWidgetState extends State with SingleTickerProvid _model.dispose(); } + void _handleUploadComplete(FFUploadedFile uploadedFile) { + setState(() { + _model.uploadedLocalFile = uploadedFile; + }); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -111,11 +121,11 @@ class _PetsPageWidgetState extends State with SingleTickerProvid ), textAlign: TextAlign.start, style: FlutterFlowTheme.of(context).bodyMedium.override( - fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context).bodyMediumFamily), - ), + fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context).bodyMediumFamily), + ), ), ), ), @@ -129,7 +139,7 @@ class _PetsPageWidgetState extends State with SingleTickerProvid Padding( padding: const EdgeInsets.fromLTRB(0, 10, 0, 20), child: MediaUploadButtonUtil( - uploadedFile: _model.uploadedLocalFile, + onUploadComplete: _handleUploadComplete, isUploading: _model.isDataUploading, labelText: FFLocalizations.of(context).getVariableText( ptText: 'Clique para adicionar a foto de seu Pet', @@ -138,8 +148,8 @@ class _PetsPageWidgetState extends State with SingleTickerProvid ), CustomInputUtil( controller: _model.textControllerName, - validator: - _model.textControllerNameValidator.asValidator(context), + validator: _model.textControllerNameValidator + .asValidator(context), focusNode: _model.textFieldFocusName, labelText: FFLocalizations.of(context) .getVariableText(ptText: 'Nome', enText: 'Name'), @@ -153,6 +163,8 @@ class _PetsPageWidgetState extends State with SingleTickerProvid padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), child: CustomInputUtil( controller: _model.textControllerSpecies, + validator: _model.textControllerSpeciesValidator + .asValidator(context), focusNode: _model.textFieldFocusSpecies, labelText: FFLocalizations.of(context).getVariableText( ptText: 'Espécie', enText: 'Species'), @@ -166,6 +178,8 @@ class _PetsPageWidgetState extends State with SingleTickerProvid padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), child: CustomInputUtil( controller: _model.textControllerRace, + validator: _model.textControllerRaceValidator + .asValidator(context), focusNode: _model.textFieldFocusRace, labelText: FFLocalizations.of(context) .getVariableText(ptText: 'Raça', enText: 'Race'), @@ -179,6 +193,8 @@ class _PetsPageWidgetState extends State with SingleTickerProvid padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), child: CustomInputUtil( controller: _model.textControllerColor, + validator: _model.textControllerColorValidator + .asValidator(context), focusNode: _model.textFieldFocusColor, labelText: FFLocalizations.of(context) .getVariableText(ptText: 'Cor', enText: 'Color'), @@ -206,7 +222,7 @@ class _PetsPageWidgetState extends State with SingleTickerProvid focusNode: _model.textFieldFocusData, readOnly: true, autovalidateMode: - AutovalidateMode.onUserInteraction, + AutovalidateMode.onUserInteraction, autofocus: false, obscureText: false, decoration: InputDecoration( @@ -214,17 +230,17 @@ class _PetsPageWidgetState extends State with SingleTickerProvid labelStyle: FlutterFlowTheme.of(context) .labelMedium .override( - fontFamily: - FlutterFlowTheme.of(context) - .labelMediumFamily, - color: FlutterFlowTheme.of(context) - .primaryText, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap() - .containsKey( - FlutterFlowTheme.of(context) - .labelMediumFamily), - ), + fontFamily: + FlutterFlowTheme.of(context) + .labelMediumFamily, + color: FlutterFlowTheme.of(context) + .primaryText, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap() + .containsKey( + FlutterFlowTheme.of(context) + .labelMediumFamily), + ), hintText: FFLocalizations.of(context) .getVariableText( ptText: 'Data de Nascimento', @@ -233,25 +249,26 @@ class _PetsPageWidgetState extends State with SingleTickerProvid hintStyle: FlutterFlowTheme.of(context) .labelMedium .override( - fontFamily: - FlutterFlowTheme.of(context) - .labelMediumFamily, - color: FlutterFlowTheme.of(context) - .primaryText, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap() - .containsKey( - FlutterFlowTheme.of(context) - .labelMediumFamily), - lineHeight: 1.0, - ), + fontFamily: + FlutterFlowTheme.of(context) + .labelMediumFamily, + color: FlutterFlowTheme.of(context) + .primaryText, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap() + .containsKey( + FlutterFlowTheme.of(context) + .labelMediumFamily), + lineHeight: 1.0, + ), enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: FlutterFlowTheme.of(context) .customColor6, width: 0.5, ), - borderRadius: BorderRadius.circular(10.0), + borderRadius: + BorderRadius.circular(10.0), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide( @@ -259,44 +276,49 @@ class _PetsPageWidgetState extends State with SingleTickerProvid .primary, width: 0.5, ), - borderRadius: BorderRadius.circular(10.0), + borderRadius: + BorderRadius.circular(10.0), ), errorBorder: OutlineInputBorder( borderSide: BorderSide( - color: - FlutterFlowTheme.of(context).error, + color: FlutterFlowTheme.of(context) + .error, width: 0.5, ), - borderRadius: BorderRadius.circular(10.0), + borderRadius: + BorderRadius.circular(10.0), ), focusedErrorBorder: OutlineInputBorder( borderSide: BorderSide( - color: - FlutterFlowTheme.of(context).error, + color: FlutterFlowTheme.of(context) + .error, width: 0.5, ), - borderRadius: BorderRadius.circular(10.0), + borderRadius: + BorderRadius.circular(10.0), ), suffixIcon: Icon( Icons.date_range, - color: - FlutterFlowTheme.of(context).accent1, + color: FlutterFlowTheme.of(context) + .accent1, ), ), style: FlutterFlowTheme.of(context) .bodyMedium .override( - fontFamily: FlutterFlowTheme.of(context) - .bodyMediumFamily, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap() - .containsKey( - FlutterFlowTheme.of(context) - .bodyMediumFamily), - lineHeight: 1.8, - ), + fontFamily: + FlutterFlowTheme.of(context) + .bodyMediumFamily, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap() + .containsKey( + FlutterFlowTheme.of(context) + .bodyMediumFamily), + lineHeight: 1.8, + ), textAlign: TextAlign.start, - validator: _model.textControllerDataValidator + validator: _model + .textControllerDataValidator .asValidator(context), ), ), @@ -319,40 +341,44 @@ class _PetsPageWidgetState extends State with SingleTickerProvid context, child!, headerBackgroundColor: - FlutterFlowTheme.of(context) - .primary, + FlutterFlowTheme.of(context) + .primary, headerForegroundColor: - FlutterFlowTheme.of(context).info, - headerTextStyle: FlutterFlowTheme.of( - context) - .headlineLarge - .override( - fontFamily: - FlutterFlowTheme.of(context) - .headlineLargeFamily, - fontSize: 32.0, - letterSpacing: 0.0, - fontWeight: FontWeight.w600, - useGoogleFonts: GoogleFonts - .asMap() - .containsKey(FlutterFlowTheme - .of(context) - .headlineLargeFamily), - ), + FlutterFlowTheme.of(context) + .info, + headerTextStyle: + FlutterFlowTheme.of(context) + .headlineLarge + .override( + fontFamily: FlutterFlowTheme + .of(context) + .headlineLargeFamily, + fontSize: 32.0, + letterSpacing: 0.0, + fontWeight: + FontWeight.w600, + useGoogleFonts: GoogleFonts + .asMap() + .containsKey( + FlutterFlowTheme.of( + context) + .headlineLargeFamily), + ), pickerBackgroundColor: - FlutterFlowTheme.of(context) - .primaryBackground, + FlutterFlowTheme.of(context) + .primaryBackground, pickerForegroundColor: - FlutterFlowTheme.of(context) - .primaryText, + FlutterFlowTheme.of(context) + .primaryText, selectedDateTimeBackgroundColor: - FlutterFlowTheme.of(context) - .primary, + FlutterFlowTheme.of(context) + .primary, selectedDateTimeForegroundColor: - FlutterFlowTheme.of(context).info, + FlutterFlowTheme.of(context) + .info, actionButtonForegroundColor: - FlutterFlowTheme.of(context) - .primaryText, + FlutterFlowTheme.of(context) + .primaryText, iconSize: 24.0, ); }, @@ -372,17 +398,17 @@ class _PetsPageWidgetState extends State with SingleTickerProvid _model.textControllerData = TextEditingController( text: dateTimeFormat( - 'dd/MM/yyyy', - _model.selectedDate, - locale: FFLocalizations.of(context) - .languageCode, - )); + 'dd/MM/yyyy', + _model.selectedDate, + locale: FFLocalizations.of(context) + .languageCode, + )); log(_model.textControllerData.text); _model.textControllerData?.selection = TextSelection.collapsed( - offset: _model - .textControllerData!.text.length, - ); + offset: _model.textControllerData! + .text.length, + ); }); } }, @@ -390,7 +416,8 @@ class _PetsPageWidgetState extends State with SingleTickerProvid width: double.infinity, height: 80.0, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), + borderRadius: + BorderRadius.circular(10.0), ), ), ), @@ -412,15 +439,17 @@ class _PetsPageWidgetState extends State with SingleTickerProvid enText: 'Select the available options', ), textAlign: TextAlign.start, - style: FlutterFlowTheme.of(context).bodySmall.override( - fontFamily: - FlutterFlowTheme.of(context).bodySmallFamily, - letterSpacing: 0.0, - fontWeight: FontWeight.w600, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context) - .bodyMediumFamily), - ), + style: FlutterFlowTheme.of(context) + .bodySmall + .override( + fontFamily: FlutterFlowTheme.of(context) + .bodySmallFamily, + letterSpacing: 0.0, + fontWeight: FontWeight.w600, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context) + .bodyMediumFamily), + ), ), ), ), @@ -431,13 +460,14 @@ class _PetsPageWidgetState extends State with SingleTickerProvid controller: _model.dropDownValueController1 ??= FormFieldController( _model.dropDownValue1 ??= ''), + isRequired: true, changed: (val) => safeSetState(() { - _model.dropDownValue1 = val; - }), + _model.dropDownValue1 = val; + }), dropDownValue: _model.dropDownValue1, optionsLabel: [ - FFLocalizations.of(context) - .getVariableText(ptText: 'Macho', enText: 'Male'), + FFLocalizations.of(context).getVariableText( + ptText: 'Macho', enText: 'Male'), FFLocalizations.of(context).getVariableText( ptText: 'Fêmea', enText: 'Female') ], @@ -452,18 +482,19 @@ class _PetsPageWidgetState extends State with SingleTickerProvid controller: _model.dropDownValueController2 ??= FormFieldController( _model.dropDownValue2 ??= ''), + isRequired: true, changed: (val) => safeSetState(() { - _model.dropDownValue2 = val; - }), + _model.dropDownValue2 = val; + }), optionsLabel: [ - FFLocalizations.of(context) - .getVariableText(ptText: 'Mini', enText: 'Mini'), + FFLocalizations.of(context).getVariableText( + ptText: 'Mini', enText: 'Mini'), FFLocalizations.of(context).getVariableText( ptText: 'Pequeno', enText: 'Small'), FFLocalizations.of(context).getVariableText( ptText: 'Médio', enText: 'Medium'), - FFLocalizations.of(context) - .getVariableText(ptText: 'Grande', enText: 'Big'), + FFLocalizations.of(context).getVariableText( + ptText: 'Grande', enText: 'Big'), FFLocalizations.of(context).getVariableText( ptText: 'Gigante', enText: 'Giant'), ], @@ -478,25 +509,30 @@ class _PetsPageWidgetState extends State with SingleTickerProvid 24.0, 0, 0.0, 15), child: Text( FFLocalizations.of(context).getVariableText( - ptText: 'Você tem alguma observação sobre o seu Pet?', + ptText: + 'Você tem alguma observação sobre o seu Pet?', enText: - 'Do you have any observations about your Pet?', + 'Do you have any observations about your Pet?', ), textAlign: TextAlign.start, - style: FlutterFlowTheme.of(context).bodySmall.override( - fontFamily: - FlutterFlowTheme.of(context).bodySmallFamily, - letterSpacing: 0.0, - fontWeight: FontWeight.w600, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context) - .bodyMediumFamily), - ), + style: FlutterFlowTheme.of(context) + .bodySmall + .override( + fontFamily: FlutterFlowTheme.of(context) + .bodySmallFamily, + letterSpacing: 0.0, + fontWeight: FontWeight.w600, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context) + .bodyMediumFamily), + ), ), ), ), CustomInputUtil( controller: _model.textControllerObservation, + validator: _model.textControllerObservationValidator + .asValidator(context), focusNode: _model.textFieldFocusObservation, labelText: FFLocalizations.of(context).getVariableText( ptText: 'Escreva as suas observações aqui...', @@ -511,9 +547,12 @@ class _PetsPageWidgetState extends State with SingleTickerProvid Padding( padding: const EdgeInsets.fromLTRB(70, 20, 70, 30), child: SubmitButtonUtil( - labelText: FFLocalizations.of(context).getVariableText( - ptText: 'Cadastrar', enText: 'Register'), - onPressed: () {}), + labelText: FFLocalizations.of(context) + .getVariableText( + ptText: 'Cadastrar', enText: 'Register'), + onPressed: _model.isFormValid(context) + ? _model.registerPet + : null), ), ])), ], @@ -521,5 +560,3 @@ class _PetsPageWidgetState extends State with SingleTickerProvid ); } } - - diff --git a/pubspec.lock b/pubspec.lock index 7ed3b0b7..0f63eadd 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -825,18 +825,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.4" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.3" leak_tracker_testing: dependency: transitive description: @@ -913,10 +913,10 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "0.8.0" material_symbols_icons: dependency: "direct main" description: @@ -937,10 +937,10 @@ packages: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.12.0" mime: dependency: transitive description: @@ -1358,10 +1358,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.0" timeago: dependency: "direct main" description: @@ -1526,10 +1526,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.2.1" web: dependency: transitive description: