import 'dart:convert'; import 'dart:developer'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart'; import 'package:hub/components/templates_components/details_component/details_component_widget.dart'; import 'package:hub/features/backend/index.dart'; import 'package:hub/features/storage/index.dart'; import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/flutter_flow/flutter_flow_widgets.dart'; import 'package:hub/flutter_flow/form_field_controller.dart'; import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/pages/pets_page/pets_page_widget.dart'; import 'package:hub/shared/utils/dialog_util.dart'; import 'package:hub/shared/utils/image_util.dart'; import 'package:hub/shared/utils/limited_text_size.dart'; import 'package:hub/shared/utils/validator_util.dart'; class PetsPageModel extends FlutterFlowModel { PetsPageModel({ required this.isInteractive, }); late final bool isInteractive; late String devUUID = ''; late String userUUID = ''; late String cliUUID = ''; late String petAmountRegister = '0'; dynamic item; late final TabController tabBarController; VoidCallback? onUpdatePet; VoidCallback? onRegisterPet; VoidCallback? safeSetState; VoidCallback? updateImage; final GlobalKey registerFormKey = GlobalKey(); final GlobalKey updateFormKey = GlobalKey(); ApiCallResponse? petsResponse; int? petId; BuildContext? buildContext; bool isEditing = false; bool isDataUploading = false; FFUploadedFile? uploadedLocalFile; FFUploadedFile? uploadedTempFile; String? imgBase64; late String defaultDropDownText = ''; String? dropDownValue1; FormFieldController? dropDownValueController1; String? dropDownValue2; FormFieldController? dropDownValueController2; FocusNode? textFieldFocusName; TextEditingController? textControllerName; String? textControllerNameValidator(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? textFieldFocusSpecies; TextEditingController? textControllerSpecies; 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? 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; String? Function(BuildContext, String?)? textControllerColorValidator; DateTime? selectedDate; FocusNode? textFieldFocusData; TextEditingController? textControllerData; String? textControllerDataValidator(BuildContext context, String? val) { return null; } FocusNode? textFieldFocusObservation; TextEditingController? textControllerObservation; String? Function(BuildContext, String?)? textControllerObservationValidator; Future initAsync() async { defaultDropDownText = FFLocalizations.of(navigatorKey.currentContext!).getVariableText( enText: 'Select an option', ptText: 'Selecione uma opção', ); dropDownValueController1 = FormFieldController(dropDownValue1 ??= defaultDropDownText); dropDownValueController2 = FormFieldController(dropDownValue2 ??= defaultDropDownText); safeSetState?.call(); } @override void initState(BuildContext context) { initAsync(); tabBarController = TabController( vsync: Navigator.of(context), length: 2, ); textFieldFocusName = FocusNode(); textControllerName = TextEditingController(); textFieldFocusSpecies = FocusNode(); textControllerSpecies = TextEditingController(); textFieldFocusRace = FocusNode(); textControllerRace = TextEditingController(); textFieldFocusColor = FocusNode(); textControllerColor = TextEditingController(); textFieldFocusData = FocusNode(); textControllerData = TextEditingController(text: ''); textFieldFocusObservation = FocusNode(); textControllerObservation = TextEditingController(); WidgetsBinding.instance.addPostFrameCallback((_) async { devUUID = await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? ''; userUUID = await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? ''; cliUUID = await StorageHelper().get(ProfileStorageKey.clientUUID.key) ?? ''; petAmountRegister = await StorageHelper().get(LocalsStorageKey.petAmount.key) ?? ''; }); } void setEditForm() { if (item != null) petId = item['id']; // updateImage!(); (() async { final String url = 'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId'; log('img: $url'); Response response = await get(Uri.parse(url)); String base64 = base64Encode(response.bodyBytes); uploadedTempFile = await ImageUtils.convertToUploadFile(base64); updateImage?.call(); })(); textControllerName = TextEditingController(text: item != null ? item['name'] ?? '' : ''); textFieldFocusName = FocusNode(); textControllerSpecies = TextEditingController(text: item != null ? item['species'] ?? '' : ''); textFieldFocusSpecies = FocusNode(); textControllerRace = TextEditingController(text: item != null ? item['breed'] ?? '' : ''); textFieldFocusRace = FocusNode(); textControllerColor = TextEditingController(text: item != null ? item['color'] ?? '' : ''); textFieldFocusColor = FocusNode(); textControllerData = TextEditingController( text: item != null ? item['birthdayDate'] != null ? ValidatorUtil.formatDateTimePicker(item['birthdayDate']) : '' : ''); textFieldFocusData = FocusNode(); textControllerObservation = TextEditingController(text: item != null ? item['notes'] ?? '' : ''); textFieldFocusObservation = FocusNode(); item != null ? dropDownValue1 = item['gender'] ?? '' : dropDownValue1 = ''; item != null ? dropDownValue2 = item['size'] ?? '' : dropDownValue2 = ''; dropDownValueController1 = FormFieldController(dropDownValue1); dropDownValueController2 = FormFieldController(dropDownValue2); } @override void dispose() { tabBarController.dispose(); textFieldFocusName?.dispose(); textControllerName?.dispose(); textFieldFocusSpecies?.dispose(); textControllerSpecies?.dispose(); textFieldFocusRace?.dispose(); textControllerRace?.dispose(); textFieldFocusColor?.dispose(); textControllerColor?.dispose(); textFieldFocusData?.dispose(); textControllerData?.dispose(); textFieldFocusObservation?.dispose(); textControllerObservation?.dispose(); dropDownValueController1?.dispose(); dropDownValueController2?.dispose(); } bool isFormValid(BuildContext context) { if (uploadedLocalFile == null || uploadedLocalFile!.bytes!.isEmpty) { 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 (dropDownValueController1!.value == defaultDropDownText || dropDownValueController1!.value == '' || dropDownValueController1!.value == null) { return false; } if (dropDownValueController2!.value == defaultDropDownText || dropDownValueController2!.value == '' || dropDownValueController2!.value == null) { return false; } if (dropDownValue1 == 'Selecione uma opção' || dropDownValue1 == null || dropDownValue1 == '') { return false; } if (dropDownValue2 == 'Selecione uma opção' || dropDownValue2 == null || dropDownValue2 == '') { return false; } return true; } Future updatePet() async { var img = await ImageUtils.convertImageFileToBase64(uploadedLocalFile!); img = "base64;jpeg,$img"; final url = 'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId'; log('img: $url'); final response = await FreAccessWSGlobal.updatePet.call( petID: petId, image: img, birthdayDate: textControllerData!.text, color: textControllerColor!.text, breed: textControllerRace!.text, species: textControllerSpecies!.text, name: textControllerName!.text, gender: dropDownValue1!, notes: textControllerObservation!.text, size: dropDownValue2!, ); if (response.jsonBody['error'] == false) { await DialogUtil.success( buildContext!, FFLocalizations.of(buildContext!).getVariableText( enText: 'Pet successfully updated', ptText: 'Pet atualizado com sucesso', ), ).then((_) async { CachedNetworkImage.evictFromCache(url); switchTab(1); }); onUpdatePet?.call(); } else { String errorMessage; try { errorMessage = jsonDecode(response.jsonBody['error_msg'])[0]['message'].toString(); } catch (e) { errorMessage = FFLocalizations.of(buildContext!).getVariableText( enText: 'Failed to update pet', ptText: 'Falha ao atualizar o pet', ); } await DialogUtil.error(buildContext!, errorMessage); } } Future registerPet() async { var img = await ImageUtils.convertImageFileToBase64(uploadedLocalFile!); img = "base64;jpeg,$img"; final response = await FreAccessWSGlobal.registerPet.call( image: img, birthdayDate: textControllerData!.text, color: textControllerColor!.text, breed: textControllerRace!.text, species: textControllerSpecies!.text, name: textControllerName!.text, gender: dropDownValue1!, size: dropDownValue2!, notes: textControllerObservation!.text, ); if (response.jsonBody['error'] == false) { await DialogUtil.success( buildContext!, FFLocalizations.of(buildContext!).getVariableText( enText: 'Pet successfully registered', ptText: 'Pet cadastrado com sucesso', ), ); onRegisterPet?.call(); } else { String errorMessage; try { errorMessage = jsonDecode(response.jsonBody['error_msg'])[0]['message'].toString(); await DialogUtil.error(buildContext!, errorMessage); } catch (e) { if (response.jsonBody['error_msg'] == "Limite de Cadastro de Pet Atingido.") { errorMessage = FFLocalizations.of(buildContext!).getVariableText( enText: 'Pet registration limit reached', ptText: 'Limite de cadastro de pets atingido', ); await DialogUtil.error(buildContext!, errorMessage); } else { await DialogUtil.errorDefault(buildContext!); } } } } void switchTab(int index) { tabBarController.animateTo(index); if (index == 1) handleEditingChanged(false); safeSetState?.call(); } void handleUploadComplete(FFUploadedFile uploadedFile) { uploadedLocalFile = uploadedFile; safeSetState?.call(); } void handleEditingChanged(bool editing) { isEditing = editing; clearFields(); } void clearFields() async { uploadedLocalFile = null; textControllerName = TextEditingController(text: ''); textControllerSpecies = TextEditingController(text: ''); textControllerRace = TextEditingController(text: ''); textControllerColor = TextEditingController(text: ''); textControllerObservation = TextEditingController(text: ''); // textControllerData = TextEditingController( // text: dateTimeFormat( // 'dd/MM/yyyy', // DateTime.now(), // )); // dropDownValue1 = ''; // dropDownValue2 = ''; // dropDownValueController1 = FormFieldController('Selecione uma opção'); // dropDownValueController2 = FormFieldController('Selecione uma opção'); } Widget buildPetDetails({ required dynamic item, required BuildContext context, required String devUUID, required String userUUID, required String cliUUID, required String cliName, required PetsPageModel model, }) { return DetailsComponentWidget( buttons: isInteractive ? [ FFButtonWidget( text: FFLocalizations.of(context).getVariableText( ptText: 'Editar', enText: 'Edit', ), icon: const Icon(Icons.edit), onPressed: () async { context.pop(); model.isEditing = true; model.item = item; model.switchTab(0); model.setEditForm(); // model.safeSetState!(); }, options: FFButtonOptions( height: 40, color: FlutterFlowTheme.of(context).primaryBackground, elevation: 0, textStyle: TextStyle( color: FlutterFlowTheme.of(context).primaryText, fontSize: LimitedFontSizeUtil.getNoResizeFont(context, 15), ), splashColor: const Color.fromARGB(95, 0, 146, 5), borderSide: BorderSide( color: FlutterFlowTheme.of(context).primaryBackground, width: 1, ), // borderRadius: 12, ), ), FFButtonWidget( text: FFLocalizations.of(context).getVariableText( ptText: 'Excluir', enText: 'Delete', ), icon: const Icon(Icons.close), onPressed: () async { showAlertDialog( context, FFLocalizations.of(context).getVariableText( ptText: 'Excluir Pet', enText: 'Delete Pet', ), FFLocalizations.of(context).getVariableText( ptText: 'Você tem certeza que deseja excluir esse pet?', enText: 'Are you sure you want to delete this pet?', ), () async { int id = item['id']; await FreAccessWSGlobal.deletePet .call( petID: id, ) .then((value) { // Navigator.pop(context, value); context.pop(value); context.pop(value); if (value == false) { showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( ptText: 'Erro ao excluir pet', enText: 'Error deleting pet', ), true, ); } else if (value == true) { showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( enText: 'Success deleting pet', ptText: 'Succeso ao excluir pet', ), false, ); } }).catchError((err, stack) { context.pop(); showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( enText: 'Error deleting pet', ptText: 'Erro ao excluir pet', ), true, ); }); }); }, options: FFButtonOptions( height: 40, color: FlutterFlowTheme.of(context).primaryBackground, elevation: 0, textStyle: TextStyle( color: FlutterFlowTheme.of(context).primaryText, fontSize: LimitedFontSizeUtil.getNoResizeFont(context, 15), ), splashColor: const Color.fromARGB(131, 255, 17, 0), borderSide: BorderSide( color: FlutterFlowTheme.of(context).primaryBackground, width: 1, ), // borderRadius: 12, ), ), ] : [], labelsHashMap: Map.from({ if (item['species'] != null && item['species'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Espécie", enText: "Species")}:': item['species'].toString().toUpperCase(), if (item['breed'] != null && item['breed'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Raça", enText: "Breed")}:': item['breed'].toString().toUpperCase(), if (item['color'] != null && item['color'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Cor", enText: "Color")}:': item['color'].toString().toUpperCase(), if (item['birthdayDate'] != null && item['birthdayDate'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Data de Nascimento", enText: "Date of Birth")}:': ValidatorUtil.formatDateTimePicker(item['birthdayDate']), if (item['gender'] != null && item['gender'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Gênero", enText: "Gender")}:': item['gender'] == 'MAC' ? FFLocalizations.of(context) .getVariableText(ptText: 'MACHO', enText: 'MALE') : FFLocalizations.of(context) .getVariableText(enText: 'FEMALE', ptText: 'FÊMEA'), if (item['size'] != null && item['size'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Porte", enText: "Size")}:': item['size'] == 'MIN' ? FFLocalizations.of(context) .getVariableText(ptText: 'MINI', enText: 'MINI') : item['size'] == 'PEQ' ? FFLocalizations.of(context) .getVariableText(ptText: 'PEQUENO', enText: 'SMALL') : item['size'] == 'MED' ? FFLocalizations.of(context).getVariableText( ptText: 'MÉDIO', enText: 'MEDIUM') : item['size'] == 'GRD' ? FFLocalizations.of(context).getVariableText( ptText: 'GRANDE', enText: 'LARGE') : item['size'] == 'GIG' ? FFLocalizations.of(context).getVariableText( ptText: 'GIGANTE', enText: 'GIANT') : '', if (item['notes'] != null && item['notes'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Observação", enText: "Notes")}:': item['notes'] ?? '', }), imagePath: 'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=${item['id'] ?? ''}', statusHashMap: [ if (item['gender'] == "MAC") Map.from({ item['name']: const Color(0xFF094CB0), }), if (item['gender'] == "FEM") Map.from({ item['name']: const Color(0xFFE463E7), }), ], ); } }