583 lines
20 KiB
Dart
583 lines
20 KiB
Dart
import 'dart:convert';
|
|
|
|
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<PetsPageWidget> {
|
|
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<FormState> registerFormKey = GlobalKey<FormState>();
|
|
final GlobalKey<FormState> updateFormKey = GlobalKey<FormState>();
|
|
|
|
ApiCallResponse? petsResponse;
|
|
int? petId;
|
|
BuildContext? buildContext;
|
|
bool isEditing = false;
|
|
|
|
bool isDataUploading = false;
|
|
FFUploadedFile? uploadedLocalFile;
|
|
FFUploadedFile? uploadedTempFile;
|
|
String? imgBase64;
|
|
|
|
late String defaultDropDownText = '';
|
|
|
|
String? dropDownValue1;
|
|
FormFieldController<String>? dropDownValueController1;
|
|
|
|
String? dropDownValue2;
|
|
FormFieldController<String>? 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<void> initAsync() async {
|
|
defaultDropDownText =
|
|
FFLocalizations.of(navigatorKey.currentContext!).getVariableText(
|
|
enText: 'Select an option',
|
|
ptText: 'Selecione uma opção',
|
|
);
|
|
dropDownValueController1 =
|
|
FormFieldController<String>(dropDownValue1 ??= defaultDropDownText);
|
|
dropDownValueController2 =
|
|
FormFieldController<String>(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 {
|
|
Response response = await get(Uri.parse(
|
|
'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId'));
|
|
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<String>(dropDownValue1);
|
|
dropDownValueController2 = FormFieldController<String>(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<void> 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';
|
|
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<void> 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<String>('Selecione uma opção');
|
|
// dropDownValueController2 = FormFieldController<String>('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) {
|
|
showSnackbar(
|
|
context,
|
|
FFLocalizations.of(context).getVariableText(
|
|
ptText: 'Erro ao excluir pet',
|
|
enText: 'Error deleting pet',
|
|
),
|
|
true,
|
|
);
|
|
} else if (value == true) {
|
|
showSnackbar(
|
|
context,
|
|
FFLocalizations.of(context).getVariableText(
|
|
enText: 'Success deleting pet',
|
|
ptText: 'Succeso ao excluir pet',
|
|
),
|
|
false,
|
|
);
|
|
}
|
|
}).catchError((err, stack) {
|
|
context.pop();
|
|
showSnackbar(
|
|
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<String, String>.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<String, Color>.from({
|
|
item['name']: const Color(0xFF094CB0),
|
|
}),
|
|
if (item['gender'] == "FEM")
|
|
Map<String, Color>.from({
|
|
item['name']: const Color(0xFFE463E7),
|
|
}),
|
|
],
|
|
);
|
|
}
|
|
}
|